d3d9/tests: Add a test for DrawIndexedPrimitiveUP().
[wine.git] / dlls / d3d9 / tests / visual.c
blob4bea1e1382df2048b7adc7d9742bcc94edfbe299
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #include <math.h>
33 #define COBJMACROS
34 #include <d3d9.h>
35 #include "wine/test.h"
37 struct vec2
39 float x, y;
42 struct vec3
44 float x, y, z;
47 struct vec4
49 float x, y, z, w;
52 static HWND create_window(void)
54 HWND hwnd;
55 RECT rect;
57 SetRect(&rect, 0, 0, 640, 480);
58 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
59 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
60 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
61 return hwnd;
64 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
66 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
67 c1 >>= 8; c2 >>= 8;
68 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
69 c1 >>= 8; c2 >>= 8;
70 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
71 c1 >>= 8; c2 >>= 8;
72 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
73 return TRUE;
76 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
78 return !strcmp(identifier->Driver, "d3d10warp.dll");
81 /* Locks a given surface and returns the color at (x,y). It's the caller's
82 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
83 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
85 DWORD color;
86 HRESULT hr;
87 D3DSURFACE_DESC desc;
88 RECT rectToLock = {x, y, x+1, y+1};
89 D3DLOCKED_RECT lockedRect;
91 hr = IDirect3DSurface9_GetDesc(surface, &desc);
92 if(FAILED(hr)) /* This is not a test */
94 trace("Can't get the surface description, hr=%08x\n", hr);
95 return 0xdeadbeef;
98 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
99 if(FAILED(hr)) /* This is not a test */
101 trace("Can't lock the surface, hr=%08x\n", hr);
102 return 0xdeadbeef;
104 switch(desc.Format) {
105 case D3DFMT_A8R8G8B8:
107 color = ((DWORD *) lockedRect.pBits)[0];
108 break;
110 default:
111 trace("Error: unknown surface format: %d\n", desc.Format);
112 color = 0xdeadbeef;
113 break;
115 hr = IDirect3DSurface9_UnlockRect(surface);
116 if(FAILED(hr))
118 trace("Can't unlock the surface, hr=%08x\n", hr);
120 return color;
123 struct surface_readback
125 IDirect3DSurface9 *surface;
126 D3DLOCKED_RECT locked_rect;
129 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
131 IDirect3DDevice9 *device;
132 D3DSURFACE_DESC desc;
133 HRESULT hr;
135 memset(rb, 0, sizeof(*rb));
136 hr = IDirect3DSurface9_GetDevice(surface, &device);
137 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
138 hr = IDirect3DSurface9_GetDesc(surface, &desc);
139 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
140 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
141 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
142 if (FAILED(hr) || !rb->surface)
144 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
145 goto error;
148 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
149 if (FAILED(hr))
151 trace("Can't read the render target data, hr %#x.\n", hr);
152 goto error;
155 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
156 if (FAILED(hr))
158 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
159 goto error;
161 IDirect3DDevice9_Release(device);
163 return;
165 error:
166 if (rb->surface)
167 IDirect3DSurface9_Release(rb->surface);
168 rb->surface = NULL;
169 IDirect3DDevice9_Release(device);
172 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
174 return rb->locked_rect.pBits
175 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
178 static void release_surface_readback(struct surface_readback *rb)
180 HRESULT hr;
182 if (!rb->surface)
183 return;
184 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
185 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
186 IDirect3DSurface9_Release(rb->surface);
189 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
191 DWORD ret;
192 IDirect3DSurface9 *rt;
193 struct surface_readback rb;
194 HRESULT hr;
196 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
197 if(FAILED(hr))
199 trace("Can't get the render target, hr %#x.\n", hr);
200 return 0xdeadbeed;
203 get_rt_readback(rt, &rb);
204 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
205 * really important for these tests
207 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
208 release_surface_readback(&rb);
210 IDirect3DSurface9_Release(rt);
211 return ret;
214 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
216 D3DPRESENT_PARAMETERS present_parameters = {0};
217 IDirect3DDevice9 *device;
219 present_parameters.Windowed = windowed;
220 present_parameters.hDeviceWindow = device_window;
221 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
222 present_parameters.BackBufferWidth = 640;
223 present_parameters.BackBufferHeight = 480;
224 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
225 present_parameters.EnableAutoDepthStencil = TRUE;
226 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
228 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
229 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
230 return device;
232 return NULL;
235 static void cleanup_device(IDirect3DDevice9 *device)
237 if (device)
239 D3DPRESENT_PARAMETERS present_parameters;
240 IDirect3DSwapChain9 *swapchain;
241 ULONG ref;
243 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
244 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
245 IDirect3DSwapChain9_Release(swapchain);
246 ref = IDirect3DDevice9_Release(device);
247 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
248 DestroyWindow(present_parameters.hDeviceWindow);
252 static void test_sanity(void)
254 IDirect3DDevice9 *device;
255 IDirect3D9 *d3d;
256 D3DCOLOR color;
257 ULONG refcount;
258 HWND window;
259 HRESULT hr;
261 window = create_window();
262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
263 ok(!!d3d, "Failed to create a D3D object.\n");
264 if (!(device = create_device(d3d, window, window, TRUE)))
266 skip("Failed to create a D3D device, skipping tests.\n");
267 goto done;
270 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
271 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
272 color = getPixelColor(device, 1, 1);
273 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
276 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
279 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
280 color = getPixelColor(device, 639, 479);
281 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
284 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
286 refcount = IDirect3DDevice9_Release(device);
287 ok(!refcount, "Device has %u references left.\n", refcount);
288 done:
289 IDirect3D9_Release(d3d);
290 DestroyWindow(window);
293 static void lighting_test(void)
295 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
296 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
297 IDirect3DDevice9 *device;
298 D3DMATERIAL9 material;
299 IDirect3D9 *d3d;
300 D3DCOLOR color;
301 ULONG refcount;
302 HWND window;
303 HRESULT hr;
304 unsigned int i;
306 static const D3DMATRIX mat =
308 1.0f, 0.0f, 0.0f, 0.0f,
309 0.0f, 1.0f, 0.0f, 0.0f,
310 0.0f, 0.0f, 1.0f, 0.0f,
311 0.0f, 0.0f, 0.0f, 1.0f,
312 }}},
313 mat_singular =
315 1.0f, 0.0f, 1.0f, 0.0f,
316 0.0f, 1.0f, 0.0f, 0.0f,
317 1.0f, 0.0f, 1.0f, 0.0f,
318 0.0f, 0.0f, 0.5f, 1.0f,
319 }}},
320 mat_transf =
322 0.0f, 0.0f, 1.0f, 0.0f,
323 0.0f, 1.0f, 0.0f, 0.0f,
324 -1.0f, 0.0f, 0.0f, 0.0f,
325 10.f, 10.0f, 10.0f, 1.0f,
326 }}},
327 mat_nonaffine =
329 1.0f, 0.0f, 0.0f, 0.0f,
330 0.0f, 1.0f, 0.0f, 0.0f,
331 0.0f, 0.0f, 1.0f, -1.0f,
332 10.f, 10.0f, 10.0f, 0.0f,
333 }}};
334 static const struct
336 struct vec3 position;
337 DWORD diffuse;
339 unlitquad[] =
341 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
342 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
343 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
344 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
346 litquad[] =
348 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
349 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
350 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
351 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
353 lighting_test[] =
355 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
356 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
357 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
358 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
360 static const struct
362 struct vec3 position;
363 struct vec3 normal;
364 DWORD diffuse;
366 unlitnquad[] =
368 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
370 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
371 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
373 litnquad[] =
375 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
377 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
378 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
380 nquad[] =
382 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
383 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
384 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
385 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
387 rotatedquad[] =
389 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
391 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
392 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
394 translatedquad[] =
396 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
398 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
399 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
401 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
402 static const struct
404 const D3DMATRIX *world_matrix;
405 const void *quad;
406 unsigned int size;
407 DWORD expected;
408 const char *message;
410 tests[] =
412 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
413 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
414 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
415 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
418 window = create_window();
419 d3d = Direct3DCreate9(D3D_SDK_VERSION);
420 ok(!!d3d, "Failed to create a D3D object.\n");
421 if (!(device = create_device(d3d, window, window, TRUE)))
423 skip("Failed to create a D3D device, skipping tests.\n");
424 goto done;
427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
430 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
434 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
435 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
447 hr = IDirect3DDevice9_SetFVF(device, fvf);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
450 hr = IDirect3DDevice9_BeginScene(device);
451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
453 /* No lights are defined... That means, lit vertices should be entirely black */
454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
456 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
457 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
461 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
462 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
463 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
466 hr = IDirect3DDevice9_SetFVF(device, nfvf);
467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
470 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
471 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
472 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
476 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
477 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
478 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
481 hr = IDirect3DDevice9_EndScene(device);
482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
484 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
485 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
486 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
487 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
488 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
489 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
490 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
491 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
493 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
495 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
496 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
498 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
501 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
504 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
506 hr = IDirect3DDevice9_BeginScene(device);
507 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
509 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
510 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
513 hr = IDirect3DDevice9_EndScene(device);
514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
516 color = getPixelColor(device, 320, 240);
517 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
520 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
521 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
522 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
523 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#x.\n", hr);
525 memset(&material, 0, sizeof(material));
526 material.Diffuse.r = 0.0;
527 material.Diffuse.g = 0.0;
528 material.Diffuse.b = 0.0;
529 material.Diffuse.a = 1.0;
530 material.Ambient.r = 0.0;
531 material.Ambient.g = 0.0;
532 material.Ambient.b = 0.0;
533 material.Ambient.a = 0.0;
534 material.Specular.r = 0.0;
535 material.Specular.g = 0.0;
536 material.Specular.b = 0.0;
537 material.Specular.a = 0.0;
538 material.Emissive.r = 0.0;
539 material.Emissive.g = 0.0;
540 material.Emissive.b = 0.0;
541 material.Emissive.a = 0.0;
542 material.Power = 0.0;
543 hr = IDirect3DDevice9_SetMaterial(device, &material);
544 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
551 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
556 hr = IDirect3DDevice9_BeginScene(device);
557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
559 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
560 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
562 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
564 hr = IDirect3DDevice9_EndScene(device);
565 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
567 color = getPixelColor(device, 320, 240);
568 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
569 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
571 refcount = IDirect3DDevice9_Release(device);
572 ok(!refcount, "Device has %u references left.\n", refcount);
573 done:
574 IDirect3D9_Release(d3d);
575 DestroyWindow(window);
578 static void test_specular_lighting(void)
580 static const unsigned int vertices_side = 5;
581 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
582 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
583 static const D3DMATRIX mat =
585 1.0f, 0.0f, 0.0f, 0.0f,
586 0.0f, 1.0f, 0.0f, 0.0f,
587 0.0f, 0.0f, 1.0f, 0.0f,
588 0.0f, 0.0f, 0.0f, 1.0f,
589 }}};
590 static const D3DLIGHT9 directional =
592 D3DLIGHT_DIRECTIONAL,
593 {0.0f, 0.0f, 0.0f, 0.0f},
594 {1.0f, 1.0f, 1.0f, 0.0f},
595 {0.0f, 0.0f, 0.0f, 0.0f},
596 {0.0f, 0.0f, 0.0f},
597 {0.0f, 0.0f, 1.0f},
599 point =
601 D3DLIGHT_POINT,
602 {0.0f, 0.0f, 0.0f, 0.0f},
603 {1.0f, 1.0f, 1.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 0.0f},
606 {0.0f, 0.0f, 0.0f},
607 100.0f,
608 0.0f,
609 0.0f, 0.0f, 1.0f,
611 spot =
613 D3DLIGHT_SPOT,
614 {0.0f, 0.0f, 0.0f, 0.0f},
615 {1.0f, 1.0f, 1.0f, 0.0f},
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {0.0f, 0.0f, 0.0f},
618 {0.0f, 0.0f, 1.0f},
619 100.0f,
620 1.0f,
621 0.0f, 0.0f, 1.0f,
622 M_PI / 12.0f, M_PI / 3.0f
624 /* The chosen range value makes the test fail when using a manhattan
625 * distance metric vs the correct euclidean distance. */
626 point_range =
628 D3DLIGHT_POINT,
629 {0.0f, 0.0f, 0.0f, 0.0f},
630 {1.0f, 1.0f, 1.0f, 0.0f},
631 {0.0f, 0.0f, 0.0f, 0.0f},
632 {0.0f, 0.0f, 0.0f},
633 {0.0f, 0.0f, 0.0f},
634 1.2f,
635 0.0f,
636 0.0f, 0.0f, 1.0f,
638 static const struct expected_color
640 unsigned int x, y;
641 D3DCOLOR color;
643 expected_directional[] =
645 {160, 120, 0x00ffffff},
646 {320, 120, 0x00ffffff},
647 {480, 120, 0x00ffffff},
648 {160, 240, 0x00ffffff},
649 {320, 240, 0x00ffffff},
650 {480, 240, 0x00ffffff},
651 {160, 360, 0x00ffffff},
652 {320, 360, 0x00ffffff},
653 {480, 360, 0x00ffffff},
655 expected_directional_local[] =
657 {160, 120, 0x003c3c3c},
658 {320, 120, 0x00717171},
659 {480, 120, 0x003c3c3c},
660 {160, 240, 0x00717171},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00717171},
663 {160, 360, 0x003c3c3c},
664 {320, 360, 0x00717171},
665 {480, 360, 0x003c3c3c},
667 expected_point[] =
669 {160, 120, 0x00282828},
670 {320, 120, 0x005a5a5a},
671 {480, 120, 0x00282828},
672 {160, 240, 0x005a5a5a},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x005a5a5a},
675 {160, 360, 0x00282828},
676 {320, 360, 0x005a5a5a},
677 {480, 360, 0x00282828},
679 expected_point_local[] =
681 {160, 120, 0x00000000},
682 {320, 120, 0x00070707},
683 {480, 120, 0x00000000},
684 {160, 240, 0x00070707},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x00070707},
687 {160, 360, 0x00000000},
688 {320, 360, 0x00070707},
689 {480, 360, 0x00000000},
691 expected_spot[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00141414},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00141414},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00141414},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00141414},
701 {480, 360, 0x00000000},
703 expected_spot_local[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00020202},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00020202},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00020202},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00020202},
713 {480, 360, 0x00000000},
715 expected_point_range[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x005a5a5a},
719 {480, 120, 0x00000000},
720 {160, 240, 0x005a5a5a},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x005a5a5a},
723 {160, 360, 0x00000000},
724 {320, 360, 0x005a5a5a},
725 {480, 360, 0x00000000},
727 static const struct
729 const D3DLIGHT9 *light;
730 BOOL local_viewer;
731 const struct expected_color *expected;
732 unsigned int expected_count;
734 tests[] =
736 {&directional, FALSE, expected_directional,
737 sizeof(expected_directional) / sizeof(expected_directional[0])},
738 {&directional, TRUE, expected_directional_local,
739 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
740 {&point, FALSE, expected_point,
741 sizeof(expected_point) / sizeof(expected_point[0])},
742 {&point, TRUE, expected_point_local,
743 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
744 {&spot, FALSE, expected_spot,
745 sizeof(expected_spot) / sizeof(expected_spot[0])},
746 {&spot, TRUE, expected_spot_local,
747 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
748 {&point_range, FALSE, expected_point_range,
749 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
751 IDirect3DDevice9 *device;
752 D3DMATERIAL9 material;
753 IDirect3D9 *d3d;
754 D3DCOLOR color;
755 ULONG refcount;
756 HWND window;
757 HRESULT hr;
758 unsigned int i, j, x, y;
759 struct
761 struct vec3 position;
762 struct vec3 normal;
763 } *quad;
764 WORD *indices;
766 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
767 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
768 for (i = 0, y = 0; y < vertices_side; ++y)
770 for (x = 0; x < vertices_side; ++x)
772 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
773 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
774 quad[i].position.z = 1.0f;
775 quad[i].normal.x = 0.0f;
776 quad[i].normal.y = 0.0f;
777 quad[i++].normal.z = -1.0f;
780 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
782 for (x = 0; x < (vertices_side - 1); ++x)
784 indices[i++] = y * vertices_side + x + 1;
785 indices[i++] = y * vertices_side + x;
786 indices[i++] = (y + 1) * vertices_side + x;
787 indices[i++] = y * vertices_side + x + 1;
788 indices[i++] = (y + 1) * vertices_side + x;
789 indices[i++] = (y + 1) * vertices_side + x + 1;
793 window = create_window();
794 d3d = Direct3DCreate9(D3D_SDK_VERSION);
795 ok(!!d3d, "Failed to create a D3D object.\n");
796 if (!(device = create_device(d3d, window, window, TRUE)))
798 skip("Failed to create a D3D device, skipping tests.\n");
799 goto done;
802 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
803 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
804 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
805 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
806 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
807 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
809 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
811 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
813 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
815 hr = IDirect3DDevice9_SetFVF(device, fvf);
816 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
818 memset(&material, 0, sizeof(material));
819 material.Specular.r = 1.0f;
820 material.Specular.g = 1.0f;
821 material.Specular.b = 1.0f;
822 material.Specular.a = 1.0f;
823 material.Power = 30.0f;
824 hr = IDirect3DDevice9_SetMaterial(device, &material);
825 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
827 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
828 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
830 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
832 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
834 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
835 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
838 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
841 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
843 hr = IDirect3DDevice9_BeginScene(device);
844 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
846 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
847 0, vertices_side * vertices_side, indices_count / 3, indices,
848 D3DFMT_INDEX16, quad, sizeof(quad[0]));
849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
851 hr = IDirect3DDevice9_EndScene(device);
852 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
854 for (j = 0; j < tests[i].expected_count; ++j)
856 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
857 ok(color_match(color, tests[i].expected[j].color, 1),
858 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
859 tests[i].expected[j].color, tests[i].expected[j].x,
860 tests[i].expected[j].y, color, i);
864 refcount = IDirect3DDevice9_Release(device);
865 ok(!refcount, "Device has %u references left.\n", refcount);
866 done:
867 IDirect3D9_Release(d3d);
868 DestroyWindow(window);
869 HeapFree(GetProcessHeap(), 0, indices);
870 HeapFree(GetProcessHeap(), 0, quad);
873 static void clear_test(void)
875 static const D3DMATRIX mat =
877 1.0f, 0.0f, 0.0f, 0.0f,
878 0.0f, 1.0f, 0.0f, 0.0f,
879 0.0f, 0.0f, 1.0f, 0.0f,
880 0.0f, 0.0f, 0.0f, 1.0f,
881 }}};
882 static const struct
884 struct vec3 position;
885 DWORD diffuse;
887 quad[] =
889 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
890 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
891 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
892 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
894 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
895 IDirect3DTexture9 *texture;
896 HRESULT hr;
897 D3DRECT rect[2];
898 D3DRECT rect_negneg;
899 DWORD color;
900 D3DVIEWPORT9 old_vp, vp;
901 RECT scissor;
902 DWORD oldColorWrite;
903 BOOL invalid_clear_failed = FALSE;
904 IDirect3DDevice9 *device;
905 IDirect3D9 *d3d;
906 ULONG refcount;
907 HWND window;
909 window = create_window();
910 d3d = Direct3DCreate9(D3D_SDK_VERSION);
911 ok(!!d3d, "Failed to create a D3D object.\n");
912 if (!(device = create_device(d3d, window, window, TRUE)))
914 skip("Failed to create a D3D device, skipping tests.\n");
915 goto done;
918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
921 /* Positive x, negative y */
922 rect[0].x1 = 0;
923 rect[0].y1 = 480;
924 rect[0].x2 = 320;
925 rect[0].y2 = 240;
927 /* Positive x, positive y */
928 rect[1].x1 = 0;
929 rect[1].y1 = 0;
930 rect[1].x2 = 320;
931 rect[1].y2 = 240;
932 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
933 * returns D3D_OK, but ignores the rectangle silently
935 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
936 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
937 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
939 /* negative x, negative y */
940 rect_negneg.x1 = 640;
941 rect_negneg.y1 = 240;
942 rect_negneg.x2 = 320;
943 rect_negneg.y2 = 0;
944 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
945 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
946 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
948 color = getPixelColor(device, 160, 360); /* lower left quad */
949 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
950 color = getPixelColor(device, 160, 120); /* upper left quad */
951 if(invalid_clear_failed) {
952 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
953 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
954 } else {
955 /* If the negative rectangle was dropped silently, the correct ones are cleared */
956 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
958 color = getPixelColor(device, 480, 360); /* lower right quad */
959 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
960 color = getPixelColor(device, 480, 120); /* upper right quad */
961 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
963 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
965 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
966 * clear the red quad in the top left part of the render target. For some reason it
967 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
968 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
969 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
970 * pick some obvious value
972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
973 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
975 /* Test how the viewport affects clears */
976 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
977 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
978 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
979 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
981 vp.X = 160;
982 vp.Y = 120;
983 vp.Width = 160;
984 vp.Height = 120;
985 vp.MinZ = 0.0;
986 vp.MaxZ = 1.0;
987 hr = IDirect3DDevice9_SetViewport(device, &vp);
988 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
990 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
992 vp.X = 320;
993 vp.Y = 240;
994 vp.Width = 320;
995 vp.Height = 240;
996 vp.MinZ = 0.0;
997 vp.MaxZ = 1.0;
998 hr = IDirect3DDevice9_SetViewport(device, &vp);
999 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1000 rect[0].x1 = 160;
1001 rect[0].y1 = 120;
1002 rect[0].x2 = 480;
1003 rect[0].y2 = 360;
1004 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1005 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1007 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1008 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1010 color = getPixelColor(device, 158, 118);
1011 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1012 color = getPixelColor(device, 162, 118);
1013 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1014 color = getPixelColor(device, 158, 122);
1015 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1016 color = getPixelColor(device, 162, 122);
1017 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1019 color = getPixelColor(device, 318, 238);
1020 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1021 color = getPixelColor(device, 322, 238);
1022 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1023 color = getPixelColor(device, 318, 242);
1024 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1025 color = getPixelColor(device, 322, 242);
1026 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1028 color = getPixelColor(device, 478, 358);
1029 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1030 color = getPixelColor(device, 482, 358);
1031 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1032 color = getPixelColor(device, 478, 362);
1033 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1034 color = getPixelColor(device, 482, 362);
1035 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1037 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1040 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1042 SetRect(&scissor, 160, 120, 480, 360);
1043 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1044 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1046 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1049 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1050 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1051 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1054 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1056 color = getPixelColor(device, 158, 118);
1057 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1058 color = getPixelColor(device, 162, 118);
1059 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1060 color = getPixelColor(device, 158, 122);
1061 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1062 color = getPixelColor(device, 162, 122);
1063 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1065 color = getPixelColor(device, 158, 358);
1066 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1067 color = getPixelColor(device, 162, 358);
1068 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1069 color = getPixelColor(device, 158, 358);
1070 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1071 color = getPixelColor(device, 162, 362);
1072 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1074 color = getPixelColor(device, 478, 118);
1075 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1076 color = getPixelColor(device, 478, 122);
1077 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1078 color = getPixelColor(device, 482, 122);
1079 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1080 color = getPixelColor(device, 482, 358);
1081 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1083 color = getPixelColor(device, 478, 358);
1084 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1085 color = getPixelColor(device, 478, 362);
1086 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1087 color = getPixelColor(device, 482, 358);
1088 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1089 color = getPixelColor(device, 482, 362);
1090 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1092 color = getPixelColor(device, 318, 238);
1093 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1094 color = getPixelColor(device, 318, 242);
1095 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1096 color = getPixelColor(device, 322, 238);
1097 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1098 color = getPixelColor(device, 322, 242);
1099 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1101 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1103 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1104 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1108 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1113 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1116 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1118 /* Colorwriteenable does not affect the clear */
1119 color = getPixelColor(device, 320, 240);
1120 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1125 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1127 rect[0].x1 = 0;
1128 rect[0].y1 = 0;
1129 rect[0].x2 = 640;
1130 rect[0].y2 = 480;
1131 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1132 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1134 color = getPixelColor(device, 320, 240);
1135 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1136 "Clear with count = 0, rect != NULL has color %08x\n", color);
1138 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1140 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1141 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1142 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1143 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1145 color = getPixelColor(device, 320, 240);
1146 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1147 "Clear with count = 1, rect = NULL has color %08x\n", color);
1149 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1151 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1152 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1153 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1155 color = getPixelColor(device, 320, 240);
1156 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1159 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1161 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1162 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1163 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1165 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1167 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1169 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1171 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1173 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1175 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1176 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1177 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1178 hr = IDirect3DDevice9_BeginScene(device);
1179 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1180 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1181 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1182 hr = IDirect3DDevice9_EndScene(device);
1183 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1185 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1186 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1188 color = getPixelColor(device, 320, 240);
1189 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1192 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1194 /* Switching to a new render target seems to be enough to make Windows pick
1195 * up on the changed render state. */
1196 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1197 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1198 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1199 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1200 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1201 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1202 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1203 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1204 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1206 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1207 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1209 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1210 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1212 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1213 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1215 color = getPixelColor(device, 64, 64);
1216 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1219 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1221 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1222 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1224 hr = IDirect3DDevice9_BeginScene(device);
1225 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1227 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1228 hr = IDirect3DDevice9_EndScene(device);
1229 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1232 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1234 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1235 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1237 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1238 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1240 color = getPixelColor(device, 320, 240);
1241 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1244 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1245 /* Switching to another surface of the same texture is also enough to make
1246 * the setting "stick". */
1247 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1248 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1249 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1250 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1253 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1255 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1256 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1258 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1259 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1261 color = getPixelColor(device, 320, 240);
1262 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1264 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1266 IDirect3DSurface9_Release(surface1);
1267 IDirect3DSurface9_Release(surface0);
1268 IDirect3DSurface9_Release(backbuffer);
1269 IDirect3DTexture9_Release(texture);
1270 refcount = IDirect3DDevice9_Release(device);
1271 ok(!refcount, "Device has %u references left.\n", refcount);
1272 done:
1273 IDirect3D9_Release(d3d);
1274 DestroyWindow(window);
1277 static void color_fill_test(void)
1279 IDirect3DSurface9 *surface;
1280 IDirect3DTexture9 *texture;
1281 D3DCOLOR fill_color, color;
1282 DWORD fill_a, expected_a;
1283 IDirect3DDevice9 *device;
1284 IDirect3D9 *d3d;
1285 ULONG refcount;
1286 HWND window;
1287 HRESULT hr;
1288 static const struct
1290 D3DPOOL pool;
1291 DWORD usage;
1292 HRESULT hr;
1294 resource_types[] =
1296 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1297 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1298 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1299 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1300 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1301 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1303 static const struct
1305 D3DFORMAT format;
1306 const char *name;
1307 enum
1309 CHECK_FILL_VALUE = 0x1,
1310 TODO_FILL_RETURN = 0x2,
1311 BLOCKS = 0x4,
1312 } flags;
1313 DWORD fill_value;
1315 formats[] =
1317 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1318 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1319 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1320 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1321 /* Real hardware reliably fills the surface with the blue channel but
1322 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1323 * channel. Don't bother checking the result because P8 surfaces are
1324 * essentially useless in d3d9. */
1325 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1326 /* Windows drivers produce different results for these formats.
1327 * No driver produces a YUV value that matches the input RGB
1328 * value, and no driver produces a proper DXT compression block.
1330 * Even the clear value 0 does not reliably produce a fill value
1331 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1333 * The YUV tests are disabled because they produce a driver-dependent
1334 * result on Wine.
1335 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1336 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1337 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0},
1338 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1339 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1340 * when created as texture. */
1342 unsigned int i;
1343 D3DLOCKED_RECT locked_rect;
1344 DWORD *surface_data;
1345 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1347 window = create_window();
1348 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1349 ok(!!d3d, "Failed to create a D3D object.\n");
1350 if (!(device = create_device(d3d, window, window, TRUE)))
1352 skip("Failed to create a D3D device, skipping tests.\n");
1353 goto done;
1356 /* Test ColorFill on a the backbuffer (should pass) */
1357 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1358 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1360 fill_color = 0x112233;
1361 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1362 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1364 color = getPixelColor(device, 0, 0);
1365 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1367 IDirect3DSurface9_Release(surface);
1369 /* Test ColorFill on a render target surface (should pass) */
1370 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1371 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1372 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1374 fill_color = 0x445566;
1375 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1376 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1378 color = getPixelColorFromSurface(surface, 0, 0);
1379 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1381 IDirect3DSurface9_Release(surface);
1383 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1384 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1385 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1386 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1388 fill_color = 0x778899;
1389 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1390 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1392 color = getPixelColorFromSurface(surface, 0, 0);
1393 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1395 IDirect3DSurface9_Release(surface);
1397 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1398 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1399 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1400 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1402 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1403 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1405 IDirect3DSurface9_Release(surface);
1407 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1408 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1409 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1411 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1412 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1414 IDirect3DSurface9_Release(surface);
1416 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1418 texture = NULL;
1419 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1420 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1421 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1422 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1423 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1425 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1426 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1427 hr, resource_types[i].hr, i);
1429 IDirect3DSurface9_Release(surface);
1430 IDirect3DTexture9_Release(texture);
1433 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1435 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1436 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1438 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1439 continue;
1442 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1443 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1444 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1446 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1447 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1448 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1450 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1451 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1452 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1454 if (SUCCEEDED(hr))
1456 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1457 if (formats[i].flags & BLOCKS)
1458 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1459 else
1460 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1463 if (formats[i].flags & CHECK_FILL_VALUE)
1465 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1466 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1467 surface_data = locked_rect.pBits;
1468 fill_a = (surface_data[0] & 0xff000000) >> 24;
1469 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1470 /* Windows drivers disagree on how to promote the 8 bit per channel
1471 * input argument to 16 bit for D3DFMT_G16R16. */
1472 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1473 abs((expected_a) - (fill_a)) < 3,
1474 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1475 formats[i].fill_value, surface_data[0], formats[i].name);
1476 hr = IDirect3DSurface9_UnlockRect(surface);
1477 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1480 IDirect3DSurface9_Release(surface);
1483 refcount = IDirect3DDevice9_Release(device);
1484 ok(!refcount, "Device has %u references left.\n", refcount);
1485 done:
1486 IDirect3D9_Release(d3d);
1487 DestroyWindow(window);
1491 * c7 mova ARGB mov ARGB
1492 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1493 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1494 * -0.4 0 0x0000ffff -1 0x0000ff00
1495 * 0.4 0 0x0000ffff 0 0x0000ffff
1496 * 1.6 2 0x00ff00ff 1 0x000000ff
1497 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1499 static void test_mova(void)
1501 IDirect3DVertexDeclaration9 *vertex_declaration;
1502 IDirect3DVertexShader9 *mova_shader;
1503 IDirect3DVertexShader9 *mov_shader;
1504 IDirect3DDevice9 *device;
1505 unsigned int i, j;
1506 IDirect3D9 *d3d;
1507 ULONG refcount;
1508 D3DCAPS9 caps;
1509 HWND window;
1510 HRESULT hr;
1512 static const DWORD mova_test[] =
1514 0xfffe0200, /* vs_2_0 */
1515 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1516 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1517 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1518 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1519 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1520 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1521 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1522 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1523 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1524 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1525 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1526 0x0000ffff /* END */
1528 static const DWORD mov_test[] =
1530 0xfffe0101, /* vs_1_1 */
1531 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1532 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1533 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1534 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1535 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1536 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1537 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1538 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1539 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1540 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1541 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1542 0x0000ffff /* END */
1544 static const struct
1546 float in[4];
1547 DWORD out;
1549 test_data[2][6] =
1552 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1553 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1554 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1555 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1556 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1557 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1560 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1561 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1562 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1563 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1564 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1565 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1568 static const struct vec3 quad[] =
1570 {-1.0f, -1.0f, 0.0f},
1571 {-1.0f, 1.0f, 0.0f},
1572 { 1.0f, -1.0f, 0.0f},
1573 { 1.0f, 1.0f, 0.0f},
1575 static const D3DVERTEXELEMENT9 decl_elements[] =
1577 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1578 D3DDECL_END()
1581 window = create_window();
1582 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1583 ok(!!d3d, "Failed to create a D3D object.\n");
1584 if (!(device = create_device(d3d, window, window, TRUE)))
1586 skip("Failed to create a D3D device, skipping tests.\n");
1587 goto done;
1590 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1591 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1592 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1594 skip("No vs_2_0 support, skipping tests.\n");
1595 IDirect3DDevice9_Release(device);
1596 goto done;
1599 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1600 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1601 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1602 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1603 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1604 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1605 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1606 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1608 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1609 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1610 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1612 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1614 DWORD color;
1616 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1617 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1619 hr = IDirect3DDevice9_BeginScene(device);
1620 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1623 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1625 hr = IDirect3DDevice9_EndScene(device);
1626 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1628 color = getPixelColor(device, 320, 240);
1629 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1630 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1632 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1633 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1636 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1639 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1642 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1643 IDirect3DVertexShader9_Release(mova_shader);
1644 IDirect3DVertexShader9_Release(mov_shader);
1645 refcount = IDirect3DDevice9_Release(device);
1646 ok(!refcount, "Device has %u references left.\n", refcount);
1647 done:
1648 IDirect3D9_Release(d3d);
1649 DestroyWindow(window);
1652 static void fog_test(void)
1654 float start = 0.0f, end = 1.0f;
1655 IDirect3DDevice9 *device;
1656 IDirect3D9 *d3d;
1657 D3DCOLOR color;
1658 ULONG refcount;
1659 D3DCAPS9 caps;
1660 HWND window;
1661 HRESULT hr;
1662 int i;
1664 /* Gets full z based fog with linear fog, no fog with specular color. */
1665 static const struct
1667 float x, y, z;
1668 D3DCOLOR diffuse;
1669 D3DCOLOR specular;
1671 untransformed_1[] =
1673 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1674 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1675 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1676 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1678 /* Ok, I am too lazy to deal with transform matrices. */
1679 untransformed_2[] =
1681 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1682 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1683 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1684 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1686 untransformed_3[] =
1688 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1689 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1690 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1691 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1693 far_quad1[] =
1695 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1696 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1697 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1698 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1700 far_quad2[] =
1702 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1703 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1704 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1705 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1707 /* Untransformed ones. Give them a different diffuse color to make the
1708 * test look nicer. It also makes making sure that they are drawn
1709 * correctly easier. */
1710 static const struct
1712 float x, y, z, rhw;
1713 D3DCOLOR diffuse;
1714 D3DCOLOR specular;
1716 transformed_1[] =
1718 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1719 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1720 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1721 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1723 transformed_2[] =
1725 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1726 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1727 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1728 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1730 static const struct
1732 struct vec3 position;
1733 DWORD diffuse;
1735 rev_fog_quads[] =
1737 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1738 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1739 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1740 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1742 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1743 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1744 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1745 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1747 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1748 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1749 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1750 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1752 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1753 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1754 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1755 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1757 static const D3DMATRIX ident_mat =
1759 1.0f, 0.0f, 0.0f, 0.0f,
1760 0.0f, 1.0f, 0.0f, 0.0f,
1761 0.0f, 0.0f, 1.0f, 0.0f,
1762 0.0f, 0.0f, 0.0f, 1.0f
1763 }}};
1764 static const D3DMATRIX world_mat1 =
1766 1.0f, 0.0f, 0.0f, 0.0f,
1767 0.0f, 1.0f, 0.0f, 0.0f,
1768 0.0f, 0.0f, 1.0f, 0.0f,
1769 0.0f, 0.0f, -0.5f, 1.0f
1770 }}};
1771 static const D3DMATRIX world_mat2 =
1773 1.0f, 0.0f, 0.0f, 0.0f,
1774 0.0f, 1.0f, 0.0f, 0.0f,
1775 0.0f, 0.0f, 1.0f, 0.0f,
1776 0.0f, 0.0f, 1.0f, 1.0f
1777 }}};
1778 static const D3DMATRIX proj_mat =
1780 1.0f, 0.0f, 0.0f, 0.0f,
1781 0.0f, 1.0f, 0.0f, 0.0f,
1782 0.0f, 0.0f, 1.0f, 0.0f,
1783 0.0f, 0.0f, -1.0f, 1.0f
1784 }}};
1785 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1786 static const WORD Indices2[] =
1788 0, 1, 2, 2, 3, 0,
1789 4, 5, 6, 6, 7, 4,
1790 8, 9, 10, 10, 11, 8,
1791 12, 13, 14, 14, 15, 12,
1794 window = create_window();
1795 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1796 ok(!!d3d, "Failed to create a D3D object.\n");
1797 if (!(device = create_device(d3d, window, window, TRUE)))
1799 skip("Failed to create a D3D device, skipping tests.\n");
1800 goto done;
1803 memset(&caps, 0, sizeof(caps));
1804 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1805 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1806 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1807 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1809 /* Setup initial states: No lighting, fog on, fog color */
1810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1811 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1813 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1815 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1817 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1818 /* Some of the tests seem to depend on the projection matrix explicitly
1819 * being set to an identity matrix, even though that's the default.
1820 * (AMD Radeon HD 6310, Windows 7) */
1821 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1822 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1824 /* First test: Both table fog and vertex fog off */
1825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1826 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1828 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1830 /* Start = 0, end = 1. Should be default, but set them */
1831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1832 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1834 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1836 hr = IDirect3DDevice9_BeginScene(device);
1837 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1839 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1840 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1842 /* Untransformed, vertex fog = NONE, table fog = NONE:
1843 * Read the fog weighting from the specular color. */
1844 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1845 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1846 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1848 /* That makes it use the Z value */
1849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1850 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1851 /* Untransformed, vertex fog != none (or table fog != none):
1852 * Use the Z value as input into the equation. */
1853 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1854 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1855 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1857 /* transformed verts */
1858 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1859 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1860 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1861 * Use specular color alpha component. */
1862 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1863 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1864 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1867 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1868 /* Transformed, table fog != none, vertex anything:
1869 * Use Z value as input to the fog equation. */
1870 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1871 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1872 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1874 hr = IDirect3DDevice9_EndScene(device);
1875 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1877 color = getPixelColor(device, 160, 360);
1878 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1879 color = getPixelColor(device, 160, 120);
1880 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1881 color = getPixelColor(device, 480, 120);
1882 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1883 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1885 color = getPixelColor(device, 480, 360);
1886 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1888 else
1890 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1891 * The settings above result in no fogging with vertex fog
1893 color = getPixelColor(device, 480, 120);
1894 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1895 trace("Info: Table fog not supported by this device\n");
1897 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1899 /* Now test the special case fogstart == fogend */
1900 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1901 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1903 hr = IDirect3DDevice9_BeginScene(device);
1904 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1906 start = 512;
1907 end = 512;
1908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1909 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1911 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1913 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1914 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1916 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1918 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1920 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1921 * Would result in a completely fog-free primitive because start > zcoord,
1922 * but because start == end, the primitive is fully covered by fog. The
1923 * same happens to the 2nd untransformed quad with z = 1.0. The third
1924 * transformed quad remains unfogged because the fogcoords are read from
1925 * the specular color and has fixed fogstart and fogend. */
1926 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1927 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1928 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1929 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1930 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1933 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1934 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1935 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1936 * Use specular color alpha component. */
1937 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1938 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1941 hr = IDirect3DDevice9_EndScene(device);
1942 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1944 color = getPixelColor(device, 160, 360);
1945 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1946 color = getPixelColor(device, 160, 120);
1947 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1948 color = getPixelColor(device, 480, 120);
1949 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1950 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1952 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1953 * but without shaders it seems to work everywhere
1955 end = 0.2;
1956 start = 0.8;
1957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1958 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1960 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1961 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1962 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1964 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1965 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1966 * so skip this for now
1968 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1969 const char *mode = (i ? "table" : "vertex");
1970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1971 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1973 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1974 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1975 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1976 hr = IDirect3DDevice9_BeginScene(device);
1977 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1978 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1979 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1980 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1981 hr = IDirect3DDevice9_EndScene(device);
1982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1984 color = getPixelColor(device, 160, 360);
1985 ok(color_match(color, 0x0000ff00, 1),
1986 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1988 color = getPixelColor(device, 160, 120);
1989 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1990 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1992 color = getPixelColor(device, 480, 120);
1993 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1994 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1996 color = getPixelColor(device, 480, 360);
1997 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1999 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2001 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2002 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2003 break;
2007 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2009 /* A simple fog + non-identity world matrix test */
2010 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2011 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2013 start = 0.0;
2014 end = 1.0;
2015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2016 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2018 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2020 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2022 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2024 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2025 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2027 hr = IDirect3DDevice9_BeginScene(device);
2028 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2030 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2031 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2033 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2034 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2035 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2037 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2038 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2040 hr = IDirect3DDevice9_EndScene(device);
2041 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2043 color = getPixelColor(device, 160, 360);
2044 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2045 "Unfogged quad has color %08x\n", color);
2046 color = getPixelColor(device, 160, 120);
2047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2048 "Fogged out quad has color %08x\n", color);
2050 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2052 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2053 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2054 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2055 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2056 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2058 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2059 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2061 hr = IDirect3DDevice9_BeginScene(device);
2062 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2064 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2065 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2067 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2068 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2069 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2070 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2071 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2072 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2074 hr = IDirect3DDevice9_EndScene(device);
2075 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2077 color = getPixelColor(device, 160, 360);
2078 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2079 color = getPixelColor(device, 160, 120);
2080 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2081 "Fogged out quad has color %08x\n", color);
2083 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2085 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2086 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2087 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2088 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2090 else
2092 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2095 /* Test RANGEFOG vs FOGTABLEMODE */
2096 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2097 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2099 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2100 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2101 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2102 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2105 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2107 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2108 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2109 * Note that the fog coordinate is interpolated linearly across the vertices,
2110 * so the different eye distance at the screen center should not matter. */
2111 start = 0.75f;
2112 end = 0.75001f;
2113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2114 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2116 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2118 /* Table fog: Range fog is not used */
2119 hr = IDirect3DDevice9_BeginScene(device);
2120 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2123 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2125 untransformed_3, sizeof(*untransformed_3));
2126 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2128 hr = IDirect3DDevice9_EndScene(device);
2129 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2131 color = getPixelColor(device, 10, 10);
2132 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2133 color = getPixelColor(device, 630, 10);
2134 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2135 color = getPixelColor(device, 10, 470);
2136 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2137 color = getPixelColor(device, 630, 470);
2138 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2140 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2141 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2143 /* Vertex fog: Rangefog is used */
2144 hr = IDirect3DDevice9_BeginScene(device);
2145 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2148 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2150 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex 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_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2160 "Rangefog with vertex fog returned color 0x%08x\n", color);
2161 color = getPixelColor(device, 630, 10);
2162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2163 "Rangefog with vertex fog returned color 0x%08x\n", color);
2164 color = getPixelColor(device, 10, 470);
2165 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2166 "Rangefog with vertex fog returned color 0x%08x\n", color);
2167 color = getPixelColor(device, 630, 470);
2168 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2169 "Rangefog with vertex fog returned color 0x%08x\n", color);
2171 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2172 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2175 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2177 else
2179 skip("Range fog or table fog not supported, skipping range fog tests\n");
2182 refcount = IDirect3DDevice9_Release(device);
2183 ok(!refcount, "Device has %u references left.\n", refcount);
2184 done:
2185 IDirect3D9_Release(d3d);
2186 DestroyWindow(window);
2189 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2190 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2191 * regardless of the actual addressing mode set. The way this test works is
2192 * that we sample in one of the corners of the cubemap with filtering enabled,
2193 * and check the interpolated color. There are essentially two reasonable
2194 * things an implementation can do: Either pick one of the faces and
2195 * interpolate the edge texel with itself (i.e., clamp within the face), or
2196 * interpolate between the edge texels of the three involved faces. It should
2197 * never involve the border color or the other side (texcoord wrapping) of a
2198 * face in the interpolation. */
2199 static void test_cube_wrap(void)
2201 IDirect3DVertexDeclaration9 *vertex_declaration;
2202 IDirect3DSurface9 *face_surface, *surface;
2203 IDirect3DCubeTexture9 *texture;
2204 D3DLOCKED_RECT locked_rect;
2205 IDirect3DDevice9 *device;
2206 unsigned int x, y, face;
2207 IDirect3D9 *d3d;
2208 ULONG refcount;
2209 D3DCAPS9 caps;
2210 HWND window;
2211 HRESULT hr;
2213 static const float quad[][6] =
2215 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2216 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2217 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2218 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2220 static const D3DVERTEXELEMENT9 decl_elements[] =
2222 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2223 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2224 D3DDECL_END()
2226 static const struct
2228 D3DTEXTUREADDRESS mode;
2229 const char *name;
2231 address_modes[] =
2233 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2234 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2235 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2236 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2237 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2240 window = create_window();
2241 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2242 ok(!!d3d, "Failed to create a D3D object.\n");
2243 if (!(device = create_device(d3d, window, window, TRUE)))
2245 skip("Failed to create a D3D device, skipping tests.\n");
2246 goto done;
2249 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2250 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2251 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2253 skip("No cube texture support, skipping tests.\n");
2254 IDirect3DDevice9_Release(device);
2255 goto done;
2258 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2259 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2260 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2261 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2263 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2264 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2265 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2267 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2268 D3DPOOL_DEFAULT, &texture, NULL);
2269 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2271 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2272 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2274 for (y = 0; y < 128; ++y)
2276 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2277 for (x = 0; x < 64; ++x)
2279 *ptr++ = 0xff0000ff;
2281 for (x = 64; x < 128; ++x)
2283 *ptr++ = 0xffff0000;
2287 hr = IDirect3DSurface9_UnlockRect(surface);
2288 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2290 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2291 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2293 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2294 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2296 IDirect3DSurface9_Release(face_surface);
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++ = 0xffff0000;
2308 for (x = 64; x < 128; ++x)
2310 *ptr++ = 0xff0000ff;
2314 hr = IDirect3DSurface9_UnlockRect(surface);
2315 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2317 /* Create cube faces */
2318 for (face = 1; face < 6; ++face)
2320 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2321 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2323 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2324 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2326 IDirect3DSurface9_Release(face_surface);
2329 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2330 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2332 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2333 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2334 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2335 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2336 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2337 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2339 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2340 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2342 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2344 DWORD color;
2346 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2347 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2348 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2349 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2351 hr = IDirect3DDevice9_BeginScene(device);
2352 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2355 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2357 hr = IDirect3DDevice9_EndScene(device);
2358 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2360 color = getPixelColor(device, 320, 240);
2361 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2362 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2363 color, address_modes[x].name);
2365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2366 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2368 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2369 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2372 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2373 IDirect3DCubeTexture9_Release(texture);
2374 IDirect3DSurface9_Release(surface);
2375 refcount = IDirect3DDevice9_Release(device);
2376 ok(!refcount, "Device has %u references left.\n", refcount);
2377 done:
2378 IDirect3D9_Release(d3d);
2379 DestroyWindow(window);
2382 static void offscreen_test(void)
2384 IDirect3DSurface9 *backbuffer, *offscreen;
2385 IDirect3DTexture9 *offscreenTexture;
2386 IDirect3DDevice9 *device;
2387 IDirect3D9 *d3d;
2388 D3DCOLOR color;
2389 ULONG refcount;
2390 HWND window;
2391 HRESULT hr;
2393 static const float quad[][5] =
2395 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2396 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2397 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2398 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2401 window = create_window();
2402 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2403 ok(!!d3d, "Failed to create a D3D object.\n");
2404 if (!(device = create_device(d3d, window, window, TRUE)))
2406 skip("Failed to create a D3D device, skipping tests.\n");
2407 goto done;
2410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2411 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2413 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2414 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2415 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2416 if (!offscreenTexture)
2418 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2419 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2420 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2421 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2422 if (!offscreenTexture)
2424 skip("Cannot create an offscreen render target.\n");
2425 IDirect3DDevice9_Release(device);
2426 goto done;
2430 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2431 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2433 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2434 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2436 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2437 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2439 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2440 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2441 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2442 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2443 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2444 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2445 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2446 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2448 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2450 hr = IDirect3DDevice9_BeginScene(device);
2451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2453 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2454 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2455 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2456 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2458 /* Draw without textures - Should result in a white quad. */
2459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2460 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2462 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2463 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2464 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2465 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2467 /* This time with the texture. */
2468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2469 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2471 hr = IDirect3DDevice9_EndScene(device);
2472 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2474 /* Center quad - should be white */
2475 color = getPixelColor(device, 320, 240);
2476 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2477 /* Some quad in the cleared part of the texture */
2478 color = getPixelColor(device, 170, 240);
2479 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2480 /* Part of the originally cleared back buffer */
2481 color = getPixelColor(device, 10, 10);
2482 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2483 color = getPixelColor(device, 10, 470);
2484 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2486 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2488 IDirect3DSurface9_Release(backbuffer);
2489 IDirect3DTexture9_Release(offscreenTexture);
2490 IDirect3DSurface9_Release(offscreen);
2491 refcount = IDirect3DDevice9_Release(device);
2492 ok(!refcount, "Device has %u references left.\n", refcount);
2493 done:
2494 IDirect3D9_Release(d3d);
2495 DestroyWindow(window);
2498 /* This test tests fog in combination with shaders.
2499 * What's tested: linear fog (vertex and table) with pixel shader
2500 * linear table fog with non foggy vertex shader
2501 * vertex fog with foggy vertex shader, non-linear
2502 * fog with shader, non-linear fog with foggy shader,
2503 * linear table fog with foggy shader */
2504 static void fog_with_shader_test(void)
2506 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2507 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2508 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2509 IDirect3DDevice9 *device;
2510 unsigned int i, j;
2511 IDirect3D9 *d3d;
2512 ULONG refcount;
2513 D3DCAPS9 caps;
2514 DWORD color;
2515 HWND window;
2516 HRESULT hr;
2517 union
2519 float f;
2520 DWORD i;
2521 } start, end;
2523 /* basic vertex shader without fog computation ("non foggy") */
2524 static const DWORD vertex_shader_code1[] =
2526 0xfffe0101, /* vs_1_1 */
2527 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2528 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2529 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2530 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2531 0x0000ffff
2533 /* basic vertex shader with reversed fog computation ("foggy") */
2534 static const DWORD vertex_shader_code2[] =
2536 0xfffe0101, /* vs_1_1 */
2537 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2538 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2539 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2540 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2541 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2542 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2543 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2544 0x0000ffff
2546 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2547 static const DWORD vertex_shader_code3[] =
2549 0xfffe0200, /* vs_2_0 */
2550 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2551 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2552 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2553 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2554 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2555 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2556 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2557 0x0000ffff
2559 /* basic pixel shader */
2560 static const DWORD pixel_shader_code[] =
2562 0xffff0101, /* ps_1_1 */
2563 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2564 0x0000ffff
2566 static const DWORD pixel_shader_code2[] =
2568 0xffff0200, /* ps_2_0 */
2569 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2570 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2571 0x0000ffff
2573 struct
2575 struct vec3 position;
2576 DWORD diffuse;
2578 quad[] =
2580 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2581 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2582 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2583 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2585 static const D3DVERTEXELEMENT9 decl_elements[] =
2587 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2588 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2589 D3DDECL_END()
2591 /* This reference data was collected on a nVidia GeForce 7600GS driver
2592 * version 84.19 DirectX version 9.0c on Windows XP. */
2593 static const struct test_data_t
2595 int vshader;
2596 int pshader;
2597 D3DFOGMODE vfog;
2598 D3DFOGMODE tfog;
2599 unsigned int color[11];
2601 test_data[] =
2603 /* only pixel shader: */
2604 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2605 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2606 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2607 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2608 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2609 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2610 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2611 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2612 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2613 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2614 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2615 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2616 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2617 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2618 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2620 /* vertex shader */
2621 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2622 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2623 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2624 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2625 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2626 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2627 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2628 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2629 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2631 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2632 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2633 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2634 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2638 /* vertex shader and pixel shader */
2639 /* The next 4 tests would read the fog coord output, but it isn't available.
2640 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2641 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2642 * These tests should be disabled if some other hardware behaves differently
2644 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2645 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2646 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2647 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2648 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2649 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2650 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2651 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2652 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2653 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2654 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2655 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2657 /* These use the Z coordinate with linear table fog */
2658 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2659 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2660 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2661 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2664 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2665 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2666 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2667 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2668 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2669 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2671 /* Non-linear table fog without fog coord */
2672 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2673 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2674 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2675 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2676 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2677 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2679 /* These tests fail on older Nvidia drivers */
2680 /* foggy vertex shader */
2681 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2682 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2683 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2684 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2685 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2686 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2687 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2688 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2689 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2690 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2691 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2692 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2694 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2695 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2696 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2697 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2698 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2699 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2700 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2701 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2702 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2703 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2704 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2705 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2707 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2708 * all using the fixed fog-coord linear fog
2710 /* vs_1_1 with ps_1_1 */
2711 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2712 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2713 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2714 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2715 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2716 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2718 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2719 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2720 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2721 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2722 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2724 /* vs_2_0 with ps_1_1 */
2725 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2726 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2727 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2728 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2729 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2730 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2731 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2732 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2733 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2735 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2736 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2738 /* vs_1_1 with ps_2_0 */
2739 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2740 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2741 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2742 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2743 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2744 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2745 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2746 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2747 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2748 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2749 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2750 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2752 /* vs_2_0 with ps_2_0 */
2753 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2754 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2755 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2756 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2757 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2758 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2759 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2760 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2761 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2762 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2763 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2764 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2766 /* These use table fog. Here the shader-provided fog coordinate is
2767 * ignored and the z coordinate used instead
2769 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2770 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2771 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2772 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2773 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2774 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2775 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2776 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2777 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2779 static const D3DMATRIX identity =
2781 1.0f, 0.0f, 0.0f, 0.0f,
2782 0.0f, 1.0f, 0.0f, 0.0f,
2783 0.0f, 0.0f, 1.0f, 0.0f,
2784 0.0f, 0.0f, 0.0f, 1.0f,
2785 }}};
2787 window = create_window();
2788 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2789 ok(!!d3d, "Failed to create a D3D object.\n");
2790 if (!(device = create_device(d3d, window, window, TRUE)))
2792 skip("Failed to create a D3D device, skipping tests.\n");
2793 goto done;
2796 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2797 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2798 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2800 skip("No shader model 2 support, skipping tests.\n");
2801 IDirect3DDevice9_Release(device);
2802 goto done;
2805 /* NOTE: Changing these values will not affect the tests with foggy vertex
2806 * shader, as the values are hardcoded in the shader. */
2807 start.f = 0.1f;
2808 end.f = 0.9f;
2810 /* Some of the tests seem to depend on the projection matrix explicitly
2811 * being set to an identity matrix, even though that's the default.
2812 * (AMD Radeon HD 6310, Windows 7) */
2813 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2814 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2816 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2817 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2818 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2819 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2820 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2821 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2822 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2823 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2824 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2825 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2826 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2827 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2829 /* Setup initial states: No lighting, fog on, fog color */
2830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2831 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2833 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2835 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2836 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2837 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2840 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2842 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2844 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2846 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2848 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2850 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2852 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2853 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2854 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2855 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2857 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2859 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2861 for(j=0; j < 11; j++)
2863 /* Don't use the whole zrange to prevent rounding errors */
2864 quad[0].position.z = 0.001f + (float)j / 10.02f;
2865 quad[1].position.z = 0.001f + (float)j / 10.02f;
2866 quad[2].position.z = 0.001f + (float)j / 10.02f;
2867 quad[3].position.z = 0.001f + (float)j / 10.02f;
2869 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2872 hr = IDirect3DDevice9_BeginScene(device);
2873 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2876 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2878 hr = IDirect3DDevice9_EndScene(device);
2879 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2881 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2882 color = getPixelColor(device, 128, 240);
2883 ok(color_match(color, test_data[i].color[j], 13),
2884 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2885 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2888 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2890 IDirect3DVertexShader9_Release(vertex_shader[1]);
2891 IDirect3DVertexShader9_Release(vertex_shader[2]);
2892 IDirect3DVertexShader9_Release(vertex_shader[3]);
2893 IDirect3DPixelShader9_Release(pixel_shader[1]);
2894 IDirect3DPixelShader9_Release(pixel_shader[2]);
2895 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2896 refcount = IDirect3DDevice9_Release(device);
2897 ok(!refcount, "Device has %u references left.\n", refcount);
2898 done:
2899 IDirect3D9_Release(d3d);
2900 DestroyWindow(window);
2903 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2904 unsigned int i, x, y;
2905 HRESULT hr;
2906 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2907 D3DLOCKED_RECT locked_rect;
2909 /* Generate the textures */
2910 for(i=0; i<2; i++)
2912 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2913 D3DPOOL_MANAGED, &texture[i], NULL);
2914 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2916 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2917 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2918 for (y = 0; y < 128; ++y)
2920 if(i)
2921 { /* Set up black texture with 2x2 texel white spot in the middle */
2922 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2923 for (x = 0; x < 128; ++x)
2925 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2928 else
2929 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2930 * (if multiplied with bumpenvmat)
2932 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2933 for (x = 0; x < 128; ++x)
2935 if(abs(x-64)>abs(y-64))
2937 if(x < 64)
2938 *ptr++ = 0xc000;
2939 else
2940 *ptr++ = 0x4000;
2942 else
2944 if(y < 64)
2945 *ptr++ = 0x0040;
2946 else
2947 *ptr++ = 0x00c0;
2952 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2953 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2955 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2956 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2958 /* Disable texture filtering */
2959 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2960 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2961 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2962 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2964 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2965 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2966 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2967 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2971 /* Test the behavior of the texbem instruction with normal 2D and projective
2972 * 2D textures. */
2973 static void texbem_test(void)
2975 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2976 /* Use asymmetric matrix to test loading. */
2977 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2978 IDirect3DPixelShader9 *pixel_shader = NULL;
2979 IDirect3DTexture9 *texture1, *texture2;
2980 IDirect3DTexture9 *texture = NULL;
2981 D3DLOCKED_RECT locked_rect;
2982 IDirect3DDevice9 *device;
2983 IDirect3D9 *d3d;
2984 ULONG refcount;
2985 D3DCAPS9 caps;
2986 DWORD color;
2987 HWND window;
2988 HRESULT hr;
2989 int i;
2991 static const DWORD pixel_shader_code[] =
2993 0xffff0101, /* ps_1_1*/
2994 0x00000042, 0xb00f0000, /* tex t0*/
2995 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2996 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2997 0x0000ffff
2999 static const DWORD double_texbem_code[] =
3001 0xffff0103, /* ps_1_3 */
3002 0x00000042, 0xb00f0000, /* tex t0 */
3003 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3004 0x00000042, 0xb00f0002, /* tex t2 */
3005 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3006 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3007 0x0000ffff /* end */
3009 static const float quad[][7] =
3011 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3012 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3013 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3014 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3016 static const float quad_proj[][9] =
3018 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3019 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3020 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3021 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3023 static const float double_quad[] =
3025 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3026 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3027 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3028 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3030 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3033 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3034 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3035 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3036 D3DDECL_END()
3039 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3040 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3041 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3042 D3DDECL_END()
3046 window = create_window();
3047 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3048 ok(!!d3d, "Failed to create a D3D object.\n");
3049 if (!(device = create_device(d3d, window, window, TRUE)))
3051 skip("Failed to create a D3D device, skipping tests.\n");
3052 goto done;
3055 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3056 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3057 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3059 skip("No ps_1_1 support, skipping tests.\n");
3060 IDirect3DDevice9_Release(device);
3061 goto done;
3064 generate_bumpmap_textures(device);
3066 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3067 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3068 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3069 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3070 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3072 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3073 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3075 for(i=0; i<2; i++)
3077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3080 if(i)
3082 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3083 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3086 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3087 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3088 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3089 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3091 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3092 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3093 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3094 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3096 hr = IDirect3DDevice9_BeginScene(device);
3097 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3099 if(!i)
3100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3101 else
3102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3105 hr = IDirect3DDevice9_EndScene(device);
3106 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3108 /* The Window 8 testbot (WARP) seems to use the transposed
3109 * D3DTSS_BUMPENVMAT matrix. */
3110 color = getPixelColor(device, 160, 240);
3111 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3112 "Got unexpected color 0x%08x.\n", color);
3113 color = getPixelColor(device, 480, 240);
3114 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3115 "Got unexpected color 0x%08x.\n", color);
3116 color = getPixelColor(device, 320, 120);
3117 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3118 "Got unexpected color 0x%08x.\n", color);
3119 color = getPixelColor(device, 320, 360);
3120 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3121 "Got unexpected color 0x%08x.\n", color);
3123 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3124 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3126 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3127 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3128 IDirect3DPixelShader9_Release(pixel_shader);
3130 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3131 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3132 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3135 /* clean up */
3136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3137 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3139 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3140 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3142 for(i=0; i<2; i++)
3144 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3145 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3146 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3147 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3148 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3149 IDirect3DTexture9_Release(texture);
3152 /* Test double texbem */
3153 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3154 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3155 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3156 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3157 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3158 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3159 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3160 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3162 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3163 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3164 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3165 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3167 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3168 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3170 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3171 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3172 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3173 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3174 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3175 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3178 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3179 #define tex 0x00ff0000
3180 #define tex1 0x0000ff00
3181 #define origin 0x000000ff
3182 static const DWORD pixel_data[] = {
3183 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3184 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3185 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3186 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3187 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3188 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3189 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3190 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3192 #undef tex1
3193 #undef tex2
3194 #undef origin
3196 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3197 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3198 for(i = 0; i < 8; i++) {
3199 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3201 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3202 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3205 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3206 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3207 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3208 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3209 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3210 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3211 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3212 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3213 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3214 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3215 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3216 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3218 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3219 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3220 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3221 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3222 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3223 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3224 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3225 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3226 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3227 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3229 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3230 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3231 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3232 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3233 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3234 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3235 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3236 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3237 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3238 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3243 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3244 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3245 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3246 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3247 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3248 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3249 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3250 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3251 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3252 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3253 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3254 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3257 hr = IDirect3DDevice9_BeginScene(device);
3258 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3259 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3260 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3261 hr = IDirect3DDevice9_EndScene(device);
3262 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3263 /* The Window 8 testbot (WARP) seems to use the transposed
3264 * D3DTSS_BUMPENVMAT matrix. */
3265 color = getPixelColor(device, 320, 240);
3266 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3267 "Got unexpected color 0x%08x.\n", color);
3269 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3270 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3272 IDirect3DPixelShader9_Release(pixel_shader);
3273 IDirect3DTexture9_Release(texture);
3274 IDirect3DTexture9_Release(texture1);
3275 IDirect3DTexture9_Release(texture2);
3276 refcount = IDirect3DDevice9_Release(device);
3277 ok(!refcount, "Device has %u references left.\n", refcount);
3278 done:
3279 IDirect3D9_Release(d3d);
3280 DestroyWindow(window);
3283 static void z_range_test(void)
3285 IDirect3DVertexShader9 *shader;
3286 IDirect3DDevice9 *device;
3287 IDirect3D9 *d3d;
3288 ULONG refcount;
3289 D3DCAPS9 caps;
3290 DWORD color;
3291 HWND window;
3292 HRESULT hr;
3294 static const struct
3296 struct vec3 position;
3297 DWORD diffuse;
3299 quad[] =
3301 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3302 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3303 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3304 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3306 quad2[] =
3308 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3309 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3310 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3311 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3313 static const struct
3315 struct vec4 position;
3316 DWORD diffuse;
3318 quad3[] =
3320 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3321 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3322 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3323 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3325 quad4[] =
3327 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3328 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3329 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3330 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3332 static const DWORD shader_code[] =
3334 0xfffe0101, /* vs_1_1 */
3335 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3336 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3337 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3338 0x0000ffff /* end */
3340 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3341 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3343 window = create_window();
3344 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3345 ok(!!d3d, "Failed to create a D3D object.\n");
3346 if (!(device = create_device(d3d, window, window, TRUE)))
3348 skip("Failed to create a D3D device, skipping tests.\n");
3349 goto done;
3352 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3353 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3355 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3356 * then call Present. Then clear the color buffer to make sure it has some defined content
3357 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3358 * by the depth value. */
3359 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3360 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3362 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3363 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3364 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3367 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3369 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3371 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3373 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3374 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3375 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3376 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3377 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3379 hr = IDirect3DDevice9_BeginScene(device);
3380 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3382 /* Test the untransformed vertex path */
3383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3386 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3388 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3390 /* Test the transformed vertex path */
3391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3392 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3395 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3397 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3399 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3401 hr = IDirect3DDevice9_EndScene(device);
3402 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3404 /* Do not test the exact corner pixels, but go pretty close to them */
3406 /* Clipped because z > 1.0 */
3407 color = getPixelColor(device, 28, 238);
3408 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3409 color = getPixelColor(device, 28, 241);
3410 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3411 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3412 else
3413 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3415 /* Not clipped, > z buffer clear value(0.75).
3417 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3418 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3419 * equal to a stored depth buffer value of 0.5. */
3420 color = getPixelColor(device, 31, 238);
3421 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3422 color = getPixelColor(device, 31, 241);
3423 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3424 color = getPixelColor(device, 100, 238);
3425 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3426 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3427 color = getPixelColor(device, 100, 241);
3428 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3429 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3431 /* Not clipped, < z buffer clear value */
3432 color = getPixelColor(device, 104, 238);
3433 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3434 color = getPixelColor(device, 104, 241);
3435 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3436 color = getPixelColor(device, 318, 238);
3437 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3438 color = getPixelColor(device, 318, 241);
3439 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3441 /* Clipped because z < 0.0 */
3442 color = getPixelColor(device, 321, 238);
3443 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3444 color = getPixelColor(device, 321, 241);
3445 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3446 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3447 else
3448 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3450 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3451 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3453 /* Test the shader path */
3454 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3456 skip("Vertex shaders not supported, skipping tests.\n");
3457 IDirect3DDevice9_Release(device);
3458 goto done;
3460 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3461 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3464 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3466 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3468 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3469 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3471 hr = IDirect3DDevice9_BeginScene(device);
3472 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3474 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3475 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3477 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3480 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3481 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3482 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3484 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3486 hr = IDirect3DDevice9_EndScene(device);
3487 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3489 IDirect3DVertexShader9_Release(shader);
3491 /* Z < 1.0 */
3492 color = getPixelColor(device, 28, 238);
3493 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3495 /* 1.0 < z < 0.75 */
3496 color = getPixelColor(device, 31, 238);
3497 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3498 color = getPixelColor(device, 100, 238);
3499 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3500 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3502 /* 0.75 < z < 0.0 */
3503 color = getPixelColor(device, 104, 238);
3504 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3505 color = getPixelColor(device, 318, 238);
3506 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3508 /* 0.0 < z */
3509 color = getPixelColor(device, 321, 238);
3510 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3512 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3513 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3515 refcount = IDirect3DDevice9_Release(device);
3516 ok(!refcount, "Device has %u references left.\n", refcount);
3517 done:
3518 IDirect3D9_Release(d3d);
3519 DestroyWindow(window);
3522 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3524 D3DSURFACE_DESC desc;
3525 D3DLOCKED_RECT l;
3526 HRESULT hr;
3527 unsigned int x, y;
3528 DWORD *mem;
3530 memset(&desc, 0, sizeof(desc));
3531 memset(&l, 0, sizeof(l));
3532 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3533 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3534 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3535 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3536 if(FAILED(hr)) return;
3538 for(y = 0; y < desc.Height; y++)
3540 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3541 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3543 mem[x] = color;
3546 hr = IDirect3DSurface9_UnlockRect(surface);
3547 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3550 static void stretchrect_test(void)
3552 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3553 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3554 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3555 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3556 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3557 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3558 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3559 IDirect3DSurface9 *backbuffer;
3560 IDirect3DDevice9 *device;
3561 IDirect3D9 *d3d;
3562 D3DCOLOR color;
3563 ULONG refcount;
3564 HWND window;
3565 HRESULT hr;
3567 static const RECT src_rect = {0, 0, 640, 480};
3568 static const RECT src_rect_flipy = {0, 480, 640, 0};
3569 static const RECT dst_rect = {0, 0, 640, 480};
3570 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3571 static const RECT src_rect64 = {0, 0, 64, 64};
3572 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3573 static const RECT dst_rect64 = {0, 0, 64, 64};
3574 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3576 window = create_window();
3577 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3578 ok(!!d3d, "Failed to create a D3D object.\n");
3579 if (!(device = create_device(d3d, window, window, TRUE)))
3581 skip("Failed to create a D3D device, skipping tests.\n");
3582 goto done;
3585 /* Create our temporary surfaces in system memory. */
3586 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3587 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3588 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3589 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3590 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3591 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3593 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3594 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3595 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3596 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3597 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3598 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3599 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3600 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3601 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3602 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3604 /* Create render target surfaces. */
3605 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3606 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3607 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3608 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3609 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3610 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3611 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3612 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3613 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3614 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3615 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3617 /* Create render target textures. */
3618 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3619 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3620 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3621 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3622 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3624 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3625 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3626 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3627 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3628 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3629 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3630 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3631 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3632 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3633 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3634 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3635 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3636 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3637 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3639 /* Create regular textures in D3DPOOL_DEFAULT. */
3640 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3641 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3642 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3643 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3644 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3645 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3646 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3647 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3648 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3649 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3650 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3651 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3653 /**********************************************************************
3654 * Tests for when the source parameter is an offscreen plain surface. *
3655 **********************************************************************/
3657 /* Fill the offscreen 64x64 surface with green. */
3658 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3660 /* offscreenplain ==> offscreenplain, same size. */
3661 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3662 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3663 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3664 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3665 /* Blit without scaling. */
3666 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3667 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3668 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3669 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3670 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3671 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3672 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3673 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3674 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3675 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3676 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3678 /* offscreenplain ==> rendertarget texture, same size. */
3679 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3680 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3681 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3682 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3683 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3684 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3685 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3686 /* Blit without scaling. */
3687 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3688 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3690 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3691 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3692 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3693 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3694 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3695 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3696 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3697 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3699 /* offscreenplain ==> rendertarget surface, same size. */
3700 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3701 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3702 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3703 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3704 /* Blit without scaling. */
3705 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3706 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3707 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3708 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3709 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3710 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3711 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3712 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3713 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3714 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3715 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3717 /* offscreenplain ==> texture, same size (should fail). */
3718 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3719 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3721 /* Fill the smaller offscreen surface with red. */
3722 fill_surface(surf_offscreen32, 0xffff0000, 0);
3724 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3725 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3726 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3728 /* offscreenplain ==> rendertarget texture, scaling. */
3729 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3730 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3731 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3732 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3733 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3734 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3735 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3737 /* offscreenplain ==> rendertarget surface, scaling. */
3738 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3739 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3740 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3741 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3743 /* offscreenplain ==> texture, scaling (should fail). */
3744 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3745 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3747 /*************************************************************
3748 * Tests for when the source parameter is a regular texture. *
3749 *************************************************************/
3751 /* Fill the surface of the regular texture with blue. */
3752 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3753 fill_surface(surf_temp64, 0xff0000ff, 0);
3754 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3755 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3757 /* texture ==> offscreenplain, same size. */
3758 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3759 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3761 /* texture ==> rendertarget texture, same size. */
3762 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3763 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3764 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3765 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3766 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3767 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3768 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3769 /* Blit without scaling. */
3770 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3771 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3772 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3773 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3774 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3775 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3776 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3777 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3778 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3779 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3780 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3782 /* texture ==> rendertarget surface, same size. */
3783 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3784 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3785 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3786 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3787 /* Blit without scaling. */
3788 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3789 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3791 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3792 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3793 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3794 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3795 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3796 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3797 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3798 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3800 /* texture ==> texture, same size (should fail). */
3801 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3802 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3804 /* Fill the surface of the smaller regular texture with red. */
3805 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3806 fill_surface(surf_temp32, 0xffff0000, 0);
3807 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3808 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3810 /* texture ==> offscreenplain, scaling (should fail). */
3811 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3812 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3814 /* texture ==> rendertarget texture, scaling. */
3815 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3816 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3817 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3818 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3819 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3820 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3821 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3823 /* texture ==> rendertarget surface, scaling. */
3824 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3825 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3826 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3827 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3829 /* texture ==> texture, scaling (should fail). */
3830 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3831 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3833 /******************************************************************
3834 * Tests for when the source parameter is a rendertarget texture. *
3835 ******************************************************************/
3837 /* Fill the surface of the rendertarget texture with white. */
3838 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3839 fill_surface(surf_temp64, 0xffffffff, 0);
3840 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3841 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3843 /* rendertarget texture ==> offscreenplain, same size. */
3844 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3845 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3847 /* rendertarget texture ==> rendertarget texture, same size. */
3848 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3849 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3850 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3851 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3852 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3853 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3854 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3855 /* Blit without scaling. */
3856 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3857 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3858 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3859 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3860 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3861 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3862 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3863 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3864 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3865 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3866 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3868 /* rendertarget texture ==> rendertarget surface, same size. */
3869 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3870 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3871 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3872 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3873 /* Blit without scaling. */
3874 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3875 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3876 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3877 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3878 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3879 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3880 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3881 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3882 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3883 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3884 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3886 /* rendertarget texture ==> texture, same size (should fail). */
3887 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3888 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3890 /* Fill the surface of the smaller rendertarget texture with red. */
3891 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3892 fill_surface(surf_temp32, 0xffff0000, 0);
3893 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3894 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3896 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3897 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3898 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3900 /* rendertarget texture ==> rendertarget texture, scaling. */
3901 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3902 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3903 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3904 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3905 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3906 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3907 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3909 /* rendertarget texture ==> rendertarget surface, scaling. */
3910 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3911 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3912 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3913 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3915 /* rendertarget texture ==> texture, scaling (should fail). */
3916 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3917 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3919 /******************************************************************
3920 * Tests for when the source parameter is a rendertarget surface. *
3921 ******************************************************************/
3923 /* Fill the surface of the rendertarget surface with black. */
3924 fill_surface(surf_rt64, 0xff000000, 0);
3926 /* rendertarget texture ==> offscreenplain, same size. */
3927 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3928 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3930 /* rendertarget surface ==> rendertarget texture, same size. */
3931 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3932 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3933 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3934 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3935 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3936 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3937 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3938 /* Blit without scaling. */
3939 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3940 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3941 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3942 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3943 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3944 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3945 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3946 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3947 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3948 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3949 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3951 /* rendertarget surface ==> rendertarget surface, same size. */
3952 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3953 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3954 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3955 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3956 /* Blit without scaling. */
3957 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3958 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3959 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3960 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3961 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3962 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3963 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3964 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3965 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3966 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3967 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3969 /* rendertarget surface ==> texture, same size (should fail). */
3970 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3971 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3973 /* Fill the surface of the smaller rendertarget texture with red. */
3974 fill_surface(surf_rt32, 0xffff0000, 0);
3976 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3977 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3978 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3980 /* rendertarget surface ==> rendertarget texture, scaling. */
3981 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3982 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3983 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3984 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3985 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3986 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3987 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3989 /* rendertarget surface ==> rendertarget surface, scaling. */
3990 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3991 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3992 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3993 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3995 /* rendertarget surface ==> texture, scaling (should fail). */
3996 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3997 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3999 /* backbuffer ==> surface tests (no scaling). */
4000 /* Blit with NULL rectangles. */
4001 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4002 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4003 /* Blit without scaling. */
4004 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4005 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4006 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4007 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4008 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4009 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4010 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4011 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4012 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4013 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4014 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4016 /* TODO: Test format conversions. */
4018 IDirect3DSurface9_Release(backbuffer);
4019 IDirect3DSurface9_Release(surf_rt32);
4020 IDirect3DSurface9_Release(surf_rt64);
4021 IDirect3DSurface9_Release(surf_rt_dest64);
4022 IDirect3DSurface9_Release(surf_temp32);
4023 IDirect3DSurface9_Release(surf_temp64);
4024 IDirect3DSurface9_Release(surf_offscreen32);
4025 IDirect3DSurface9_Release(surf_offscreen64);
4026 IDirect3DSurface9_Release(surf_offscreen_dest64);
4027 IDirect3DSurface9_Release(surf_tex_rt32);
4028 IDirect3DTexture9_Release(tex_rt32);
4029 IDirect3DSurface9_Release(surf_tex_rt64);
4030 IDirect3DTexture9_Release(tex_rt64);
4031 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4032 IDirect3DTexture9_Release(tex_rt_dest64);
4033 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4034 IDirect3DTexture9_Release(tex_rt_dest640_480);
4035 IDirect3DSurface9_Release(surf_tex32);
4036 IDirect3DTexture9_Release(tex32);
4037 IDirect3DSurface9_Release(surf_tex64);
4038 IDirect3DTexture9_Release(tex64);
4039 IDirect3DSurface9_Release(surf_tex_dest64);
4040 IDirect3DTexture9_Release(tex_dest64);
4041 refcount = IDirect3DDevice9_Release(device);
4042 ok(!refcount, "Device has %u references left.\n", refcount);
4043 done:
4044 IDirect3D9_Release(d3d);
4045 DestroyWindow(window);
4048 static void maxmip_test(void)
4050 IDirect3DTexture9 *texture;
4051 IDirect3DSurface9 *surface;
4052 IDirect3DDevice9 *device;
4053 IDirect3D9 *d3d;
4054 D3DCOLOR color;
4055 ULONG refcount;
4056 D3DCAPS9 caps;
4057 HWND window;
4058 HRESULT hr;
4059 DWORD ret;
4061 static const struct
4063 struct
4065 float x, y, z;
4066 float s, t;
4068 v[4];
4070 quads[] =
4073 {-1.0, -1.0, 0.0, 0.0, 0.0},
4074 {-1.0, 0.0, 0.0, 0.0, 1.0},
4075 { 0.0, -1.0, 0.0, 1.0, 0.0},
4076 { 0.0, 0.0, 0.0, 1.0, 1.0},
4079 { 0.0, -1.0, 0.0, 0.0, 0.0},
4080 { 0.0, 0.0, 0.0, 0.0, 1.0},
4081 { 1.0, -1.0, 0.0, 1.0, 0.0},
4082 { 1.0, 0.0, 0.0, 1.0, 1.0},
4085 { 0.0, 0.0, 0.0, 0.0, 0.0},
4086 { 0.0, 1.0, 0.0, 0.0, 1.0},
4087 { 1.0, 0.0, 0.0, 1.0, 0.0},
4088 { 1.0, 1.0, 0.0, 1.0, 1.0},
4091 {-1.0, 0.0, 0.0, 0.0, 0.0},
4092 {-1.0, 1.0, 0.0, 0.0, 1.0},
4093 { 0.0, 0.0, 0.0, 1.0, 0.0},
4094 { 0.0, 1.0, 0.0, 1.0, 1.0},
4098 window = create_window();
4099 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4100 ok(!!d3d, "Failed to create a D3D object.\n");
4101 if (!(device = create_device(d3d, window, window, TRUE)))
4103 skip("Failed to create a D3D device, skipping tests.\n");
4104 goto done;
4107 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4108 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4109 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4111 skip("No mipmap support, skipping tests.\n");
4112 IDirect3DDevice9_Release(device);
4113 goto done;
4116 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4117 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4118 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4120 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4121 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4122 fill_surface(surface, 0xffff0000, 0);
4123 IDirect3DSurface9_Release(surface);
4124 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4125 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4126 fill_surface(surface, 0xff00ff00, 0);
4127 IDirect3DSurface9_Release(surface);
4128 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4129 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4130 fill_surface(surface, 0xff0000ff, 0);
4131 IDirect3DSurface9_Release(surface);
4133 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4135 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4136 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4139 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4140 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4141 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4146 hr = IDirect3DDevice9_BeginScene(device);
4147 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4149 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4150 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4152 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4154 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4155 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4157 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4160 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4161 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4162 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4164 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4165 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4167 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4169 hr = IDirect3DDevice9_EndScene(device);
4170 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4172 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4173 color = getPixelColor(device, 160, 360);
4174 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4175 color = getPixelColor(device, 480, 360);
4176 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4177 color = getPixelColor(device, 480, 120);
4178 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4179 color = getPixelColor(device, 160, 120);
4180 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4182 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4184 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4185 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4187 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4188 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4190 hr = IDirect3DDevice9_BeginScene(device);
4191 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4193 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4194 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4195 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4196 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4198 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4199 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4200 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4201 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4203 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4204 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4206 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4208 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4209 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4211 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4213 hr = IDirect3DDevice9_EndScene(device);
4214 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4216 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4217 * level 3 (> levels in texture) samples from the highest level in the
4218 * texture (level 2). */
4219 color = getPixelColor(device, 160, 360);
4220 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4221 color = getPixelColor(device, 480, 360);
4222 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4223 color = getPixelColor(device, 480, 120);
4224 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4225 color = getPixelColor(device, 160, 120);
4226 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4227 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4228 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4231 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4233 hr = IDirect3DDevice9_BeginScene(device);
4234 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4236 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4238 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4239 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4240 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4241 ret = IDirect3DTexture9_SetLOD(texture, 1);
4242 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4244 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4246 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4247 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4248 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4249 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4250 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4251 ret = IDirect3DTexture9_SetLOD(texture, 2);
4252 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4254 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4256 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4257 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4258 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4259 ret = IDirect3DTexture9_SetLOD(texture, 1);
4260 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4261 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4262 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4264 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4265 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4266 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4268 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4269 ret = IDirect3DTexture9_SetLOD(texture, 1);
4270 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4271 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4272 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4274 hr = IDirect3DDevice9_EndScene(device);
4275 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4277 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4278 * level 3 (> levels in texture) samples from the highest level in the
4279 * texture (level 2). */
4280 color = getPixelColor(device, 160, 360);
4281 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4282 color = getPixelColor(device, 480, 360);
4283 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4284 color = getPixelColor(device, 480, 120);
4285 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4286 color = getPixelColor(device, 160, 120);
4287 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4289 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4290 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4292 IDirect3DTexture9_Release(texture);
4293 refcount = IDirect3DDevice9_Release(device);
4294 ok(!refcount, "Device has %u references left.\n", refcount);
4295 done:
4296 IDirect3D9_Release(d3d);
4297 DestroyWindow(window);
4300 static void release_buffer_test(void)
4302 IDirect3DVertexBuffer9 *vb;
4303 IDirect3DIndexBuffer9 *ib;
4304 IDirect3DDevice9 *device;
4305 IDirect3D9 *d3d;
4306 D3DCOLOR color;
4307 ULONG refcount;
4308 HWND window;
4309 HRESULT hr;
4310 BYTE *data;
4311 LONG ref;
4313 static const short indices[] = {3, 4, 5};
4314 static const struct
4316 struct vec3 position;
4317 DWORD diffuse;
4319 quad[] =
4321 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4322 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4323 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4325 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4326 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4327 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4330 window = create_window();
4331 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4332 ok(!!d3d, "Failed to create a D3D object.\n");
4333 if (!(device = create_device(d3d, window, window, TRUE)))
4335 skip("Failed to create a D3D device, skipping tests.\n");
4336 goto done;
4339 /* Index and vertex buffers should always be creatable */
4340 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4341 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4342 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4343 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4344 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4345 memcpy(data, quad, sizeof(quad));
4346 hr = IDirect3DVertexBuffer9_Unlock(vb);
4347 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4349 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4350 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4351 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4352 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4353 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4354 memcpy(data, indices, sizeof(indices));
4355 hr = IDirect3DIndexBuffer9_Unlock(ib);
4356 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4358 hr = IDirect3DDevice9_SetIndices(device, ib);
4359 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4360 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4361 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4362 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4363 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4365 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4367 /* Now destroy the bound index buffer and draw again */
4368 ref = IDirect3DIndexBuffer9_Release(ib);
4369 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4371 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4372 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4374 hr = IDirect3DDevice9_BeginScene(device);
4375 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4376 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4377 * D3D from making assumptions about the indices or vertices. */
4378 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4379 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4380 hr = IDirect3DDevice9_EndScene(device);
4381 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4383 color = getPixelColor(device, 160, 120);
4384 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4385 color = getPixelColor(device, 480, 360);
4386 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4391 /* Index buffer was already destroyed as part of the test */
4392 IDirect3DVertexBuffer9_Release(vb);
4393 refcount = IDirect3DDevice9_Release(device);
4394 ok(!refcount, "Device has %u references left.\n", refcount);
4395 done:
4396 IDirect3D9_Release(d3d);
4397 DestroyWindow(window);
4400 static void float_texture_test(void)
4402 IDirect3DTexture9 *texture;
4403 IDirect3DDevice9 *device;
4404 D3DLOCKED_RECT lr;
4405 IDirect3D9 *d3d;
4406 ULONG refcount;
4407 float *data;
4408 DWORD color;
4409 HWND window;
4410 HRESULT hr;
4412 static const float quad[] =
4414 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4415 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4416 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4417 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4420 window = create_window();
4421 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4422 ok(!!d3d, "Failed to create a D3D object.\n");
4423 if (!(device = create_device(d3d, window, window, TRUE)))
4425 skip("Failed to create a D3D device, skipping tests.\n");
4426 goto done;
4429 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4430 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4432 skip("D3DFMT_R32F textures not supported\n");
4433 IDirect3DDevice9_Release(device);
4434 goto done;
4437 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4438 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4440 memset(&lr, 0, sizeof(lr));
4441 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4442 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4443 data = lr.pBits;
4444 *data = 0.0;
4445 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4446 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4449 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4450 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4451 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4453 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4454 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4456 hr = IDirect3DDevice9_BeginScene(device);
4457 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4458 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4459 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4461 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4462 hr = IDirect3DDevice9_EndScene(device);
4463 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4465 color = getPixelColor(device, 240, 320);
4466 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4469 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4471 IDirect3DTexture9_Release(texture);
4472 refcount = IDirect3DDevice9_Release(device);
4473 ok(!refcount, "Device has %u references left.\n", refcount);
4474 done:
4475 IDirect3D9_Release(d3d);
4476 DestroyWindow(window);
4479 static void g16r16_texture_test(void)
4481 IDirect3DTexture9 *texture;
4482 IDirect3DDevice9 *device;
4483 D3DLOCKED_RECT lr;
4484 IDirect3D9 *d3d;
4485 ULONG refcount;
4486 DWORD *data;
4487 DWORD color;
4488 HWND window;
4489 HRESULT hr;
4491 static const float quad[] =
4493 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4494 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4495 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4496 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4499 window = create_window();
4500 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4501 ok(!!d3d, "Failed to create a D3D object.\n");
4502 if (!(device = create_device(d3d, window, window, TRUE)))
4504 skip("Failed to create a D3D device, skipping tests.\n");
4505 goto done;
4508 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4509 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4511 skip("D3DFMT_G16R16 textures not supported\n");
4512 IDirect3DDevice9_Release(device);
4513 goto done;
4516 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4517 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4519 memset(&lr, 0, sizeof(lr));
4520 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4521 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4522 data = lr.pBits;
4523 *data = 0x0f00f000;
4524 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4525 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4528 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4529 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4532 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4533 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4535 hr = IDirect3DDevice9_BeginScene(device);
4536 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4537 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4538 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4540 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4541 hr = IDirect3DDevice9_EndScene(device);
4542 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4544 color = getPixelColor(device, 240, 320);
4545 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4546 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4548 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4549 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4551 IDirect3DTexture9_Release(texture);
4552 refcount = IDirect3DDevice9_Release(device);
4553 ok(!refcount, "Device has %u references left.\n", refcount);
4554 done:
4555 IDirect3D9_Release(d3d);
4556 DestroyWindow(window);
4559 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4561 LONG x_coords[2][2] =
4563 {r.left - 1, r.left + 1},
4564 {r.right + 1, r.right - 1},
4566 LONG y_coords[2][2] =
4568 {r.top - 1, r.top + 1},
4569 {r.bottom + 1, r.bottom - 1}
4571 unsigned int i, j, x_side, y_side;
4573 for (i = 0; i < 2; ++i)
4575 for (j = 0; j < 2; ++j)
4577 for (x_side = 0; x_side < 2; ++x_side)
4579 for (y_side = 0; y_side < 2; ++y_side)
4581 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4582 DWORD color;
4583 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4585 color = getPixelColor(device, x, y);
4586 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4587 message, x, y, color, expected);
4594 struct projected_textures_test_run
4596 const char *message;
4597 DWORD flags;
4598 IDirect3DVertexDeclaration9 *decl;
4599 BOOL vs, ps;
4600 RECT rect;
4603 static void projected_textures_test(IDirect3DDevice9 *device,
4604 struct projected_textures_test_run tests[4])
4606 unsigned int i;
4608 static const DWORD vertex_shader[] =
4610 0xfffe0101, /* vs_1_1 */
4611 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4612 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4613 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4614 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4615 0x0000ffff /* end */
4617 static const DWORD pixel_shader[] =
4619 0xffff0103, /* ps_1_3 */
4620 0x00000042, 0xb00f0000, /* tex t0 */
4621 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4622 0x0000ffff /* end */
4624 IDirect3DVertexShader9 *vs = NULL;
4625 IDirect3DPixelShader9 *ps = NULL;
4626 IDirect3D9 *d3d;
4627 D3DCAPS9 caps;
4628 HRESULT hr;
4630 IDirect3DDevice9_GetDirect3D(device, &d3d);
4631 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4632 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4633 IDirect3D9_Release(d3d);
4635 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4637 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4638 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4640 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4642 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4643 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4647 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4649 hr = IDirect3DDevice9_BeginScene(device);
4650 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4652 for (i = 0; i < 4; ++i)
4654 DWORD value = 0xdeadbeef;
4655 static const float proj_quads[] =
4657 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4658 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4659 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4660 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4662 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4663 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4664 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4665 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4667 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4668 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4669 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4670 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4672 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4673 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4674 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4675 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4678 if (tests[i].vs)
4680 if (!vs)
4682 skip("Vertex shaders not supported, skipping\n");
4683 continue;
4685 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4687 else
4688 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4689 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4690 if (tests[i].ps)
4692 if (!ps)
4694 skip("Pixel shaders not supported, skipping\n");
4695 continue;
4697 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4699 else
4700 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4701 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4703 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4704 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4706 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4707 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4708 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4709 ok(SUCCEEDED(hr) && value == tests[i].flags,
4710 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4712 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4713 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4714 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4717 hr = IDirect3DDevice9_EndScene(device);
4718 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4720 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4721 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4722 if (vs) IDirect3DVertexShader9_Release(vs);
4723 if (ps) IDirect3DPixelShader9_Release(ps);
4725 for (i = 0; i < 4; ++i)
4727 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4728 check_rect(device, tests[i].rect, tests[i].message);
4731 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4732 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4735 static void texture_transform_flags_test(void)
4737 HRESULT hr;
4738 IDirect3D9 *d3d;
4739 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4740 D3DCAPS9 caps;
4741 IDirect3DTexture9 *texture = NULL;
4742 IDirect3DVolumeTexture9 *volume = NULL;
4743 IDirect3DDevice9 *device;
4744 unsigned int x, y, z;
4745 D3DLOCKED_RECT lr;
4746 D3DLOCKED_BOX lb;
4747 D3DCOLOR color;
4748 ULONG refcount;
4749 HWND window;
4750 UINT w, h;
4751 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4753 static const D3DVERTEXELEMENT9 decl_elements[] = {
4754 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4755 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4756 D3DDECL_END()
4758 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4759 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4760 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4761 D3DDECL_END()
4763 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4764 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4765 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4766 D3DDECL_END()
4768 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4769 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4770 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4771 D3DDECL_END()
4773 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4774 0x00, 0xff, 0x00, 0x00,
4775 0x00, 0x00, 0x00, 0x00,
4776 0x00, 0x00, 0x00, 0x00};
4777 static const D3DMATRIX identity =
4779 1.0f, 0.0f, 0.0f, 0.0f,
4780 0.0f, 1.0f, 0.0f, 0.0f,
4781 0.0f, 0.0f, 1.0f, 0.0f,
4782 0.0f, 0.0f, 0.0f, 1.0f,
4783 }}};
4785 window = create_window();
4786 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4787 ok(!!d3d, "Failed to create a D3D object.\n");
4788 if (!(device = create_device(d3d, window, window, TRUE)))
4790 skip("Failed to create a D3D device, skipping tests.\n");
4791 goto done;
4794 memset(&lr, 0, sizeof(lr));
4795 memset(&lb, 0, sizeof(lb));
4796 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4797 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4798 fmt = D3DFMT_A16B16G16R16;
4800 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4802 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4803 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4804 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4806 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4807 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4808 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4809 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4810 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4811 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4812 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4813 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4814 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4815 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4816 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4817 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4818 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4819 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4820 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4821 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4822 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4823 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4824 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4825 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4827 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4828 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4829 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4831 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4833 w = min(1024, caps.MaxTextureWidth);
4834 h = min(1024, caps.MaxTextureHeight);
4835 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4836 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4838 if (!texture)
4840 skip("Failed to create the test texture.\n");
4841 IDirect3DDevice9_Release(device);
4842 goto done;
4845 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4846 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4847 * 1.0 in red and green for the x and y coords
4849 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4850 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4851 for(y = 0; y < h; y++) {
4852 for(x = 0; x < w; x++) {
4853 double r_f = (double) y / (double) h;
4854 double g_f = (double) x / (double) w;
4855 if(fmt == D3DFMT_A16B16G16R16) {
4856 unsigned short r, g;
4857 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4858 r = (unsigned short) (r_f * 65536.0);
4859 g = (unsigned short) (g_f * 65536.0);
4860 dst[0] = r;
4861 dst[1] = g;
4862 dst[2] = 0;
4863 dst[3] = 65535;
4864 } else {
4865 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4866 unsigned char r = (unsigned char) (r_f * 255.0);
4867 unsigned char g = (unsigned char) (g_f * 255.0);
4868 dst[0] = 0;
4869 dst[1] = g;
4870 dst[2] = r;
4871 dst[3] = 255;
4875 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4876 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4877 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4878 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4880 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4882 hr = IDirect3DDevice9_BeginScene(device);
4883 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4884 if(SUCCEEDED(hr))
4886 static const float quad1[] =
4888 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4889 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4890 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4891 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4893 static const float quad2[] =
4895 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4896 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4897 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4898 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4900 static const float quad3[] =
4902 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4903 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4904 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4905 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4907 static const float quad4[] =
4909 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4910 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4911 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4912 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4914 D3DMATRIX mat =
4916 0.0f, 0.0f, 0.0f, 0.0f,
4917 0.0f, 0.0f, 0.0f, 0.0f,
4918 0.0f, 0.0f, 0.0f, 0.0f,
4919 0.0f, 0.0f, 0.0f, 0.0f,
4920 }}};
4922 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4923 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4926 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4928 /* What happens with transforms enabled? */
4929 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4930 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4932 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4934 /* What happens if 4 coords are used, but only 2 given ?*/
4935 U(mat).m[2][0] = 1.0f;
4936 U(mat).m[3][1] = 1.0f;
4937 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4938 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4939 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4940 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4942 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4944 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4945 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4946 * due to the coords in the vertices. (turns out red, indeed)
4948 memset(&mat, 0, sizeof(mat));
4949 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4950 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4951 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4952 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4954 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4956 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4958 hr = IDirect3DDevice9_EndScene(device);
4959 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4961 color = getPixelColor(device, 160, 360);
4962 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4963 color = getPixelColor(device, 160, 120);
4964 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4965 color = getPixelColor(device, 480, 120);
4966 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4967 color = getPixelColor(device, 480, 360);
4968 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4969 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4970 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4973 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4975 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4977 hr = IDirect3DDevice9_BeginScene(device);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4979 if(SUCCEEDED(hr))
4981 static const float quad1[] =
4983 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4984 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4985 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4986 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4988 static const float quad2[] =
4990 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4991 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4992 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4993 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4995 static const float quad3[] =
4997 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4998 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4999 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5000 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5002 static const float quad4[] =
5004 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5005 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5006 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5007 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5009 D3DMATRIX mat =
5011 0.0f, 0.0f, 0.0f, 0.0f,
5012 0.0f, 0.0f, 0.0f, 0.0f,
5013 0.0f, 1.0f, 0.0f, 0.0f,
5014 0.0f, 0.0f, 0.0f, 0.0f,
5015 }}};
5017 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5018 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5019 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5020 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5021 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5024 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5026 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5027 * it behaves like COUNT2 because normal textures require 2 coords. */
5028 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5029 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5033 /* Just to be sure, the same as quad2 above */
5034 memset(&mat, 0, sizeof(mat));
5035 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5036 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5037 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5038 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5040 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5042 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5043 * used? And what happens to the first? */
5044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5045 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5046 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5047 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5049 hr = IDirect3DDevice9_EndScene(device);
5050 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5052 color = getPixelColor(device, 160, 360);
5053 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5054 color = getPixelColor(device, 160, 120);
5055 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5056 color = getPixelColor(device, 480, 120);
5057 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5058 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5059 color = getPixelColor(device, 480, 360);
5060 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5061 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5062 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5065 IDirect3DTexture9_Release(texture);
5067 /* Test projected textures, without any fancy matrices */
5068 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5069 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5070 if (SUCCEEDED(hr))
5072 struct projected_textures_test_run projected_tests_1[4] =
5075 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5076 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5077 decl3,
5078 FALSE, TRUE,
5079 {120, 300, 240, 390},
5082 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5083 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5084 decl3,
5085 FALSE, TRUE,
5086 {400, 360, 480, 420},
5088 /* Try with some invalid values */
5090 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5091 0xffffffff,
5092 decl3,
5093 FALSE, TRUE,
5094 {120, 60, 240, 150}
5097 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5098 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5099 decl4,
5100 FALSE, TRUE,
5101 {340, 210, 360, 225},
5104 struct projected_textures_test_run projected_tests_2[4] =
5107 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5108 D3DTTFF_PROJECTED,
5109 decl3,
5110 FALSE, TRUE,
5111 {120, 300, 240, 390},
5114 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5115 D3DTTFF_PROJECTED,
5116 decl,
5117 FALSE, TRUE,
5118 {400, 360, 480, 420},
5121 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5122 0xffffffff,
5123 decl,
5124 FALSE, TRUE,
5125 {80, 120, 160, 180},
5128 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5129 D3DTTFF_COUNT1,
5130 decl4,
5131 FALSE, TRUE,
5132 {340, 210, 360, 225},
5135 struct projected_textures_test_run projected_tests_3[4] =
5138 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5139 D3DTTFF_PROJECTED,
5140 decl3,
5141 TRUE, FALSE,
5142 {120, 300, 240, 390},
5145 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5146 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5147 decl3,
5148 TRUE, TRUE,
5149 {440, 300, 560, 390},
5152 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5153 0xffffffff,
5154 decl3,
5155 TRUE, TRUE,
5156 {120, 60, 240, 150},
5159 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5160 D3DTTFF_PROJECTED,
5161 decl3,
5162 FALSE, FALSE,
5163 {440, 60, 560, 150},
5167 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5168 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5170 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5171 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5172 for(x = 0; x < 4; x++) {
5173 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5175 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5176 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5177 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5178 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5180 projected_textures_test(device, projected_tests_1);
5181 projected_textures_test(device, projected_tests_2);
5182 projected_textures_test(device, projected_tests_3);
5184 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5185 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5186 IDirect3DTexture9_Release(texture);
5189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5190 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5191 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5192 * Thus watch out if sampling from texels between 0 and 1.
5194 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5195 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5196 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5197 if(!volume) {
5198 skip("Failed to create a volume texture\n");
5199 goto out;
5202 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5203 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5204 for(z = 0; z < 32; z++) {
5205 for(y = 0; y < 32; y++) {
5206 for(x = 0; x < 32; x++) {
5207 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5208 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5209 float r_f = (float) x / 31.0;
5210 float g_f = (float) y / 31.0;
5211 float b_f = (float) z / 31.0;
5213 if(fmt == D3DFMT_A16B16G16R16) {
5214 unsigned short *mem_s = mem;
5215 mem_s[0] = r_f * 65535.0;
5216 mem_s[1] = g_f * 65535.0;
5217 mem_s[2] = b_f * 65535.0;
5218 mem_s[3] = 65535;
5219 } else {
5220 unsigned char *mem_c = mem;
5221 mem_c[0] = b_f * 255.0;
5222 mem_c[1] = g_f * 255.0;
5223 mem_c[2] = r_f * 255.0;
5224 mem_c[3] = 255;
5229 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5230 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5232 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5233 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5235 hr = IDirect3DDevice9_BeginScene(device);
5236 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5237 if(SUCCEEDED(hr))
5239 static const float quad1[] =
5241 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5242 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5243 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5244 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5246 static const float quad2[] =
5248 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5249 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5250 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5251 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5253 static const float quad3[] =
5255 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5256 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5257 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5258 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5260 static const float quad4[] =
5262 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5263 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5264 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5265 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5267 D3DMATRIX mat =
5269 1.0f, 0.0f, 0.0f, 0.0f,
5270 0.0f, 0.0f, 1.0f, 0.0f,
5271 0.0f, 1.0f, 0.0f, 0.0f,
5272 0.0f, 0.0f, 0.0f, 1.0f,
5273 }}};
5274 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5275 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5277 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5278 * values
5280 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5281 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5282 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5283 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5285 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5287 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5288 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5289 * otherwise the w will be missing(blue).
5290 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5291 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5292 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5293 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5295 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5297 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5298 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5299 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5300 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5301 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5302 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5303 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5305 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5307 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5308 * disable. ATI extends it up to the amount of values needed for the volume texture
5310 memset(&mat, 0, sizeof(mat));
5311 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5312 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5313 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5314 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5315 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5316 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5318 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5320 hr = IDirect3DDevice9_EndScene(device);
5321 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5324 color = getPixelColor(device, 160, 360);
5325 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5326 color = getPixelColor(device, 160, 120);
5327 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5328 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5329 color = getPixelColor(device, 480, 120);
5330 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5331 color = getPixelColor(device, 480, 360);
5332 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5334 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5335 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5339 hr = IDirect3DDevice9_BeginScene(device);
5340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5341 if(SUCCEEDED(hr))
5343 static const float quad1[] =
5345 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5346 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5347 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5348 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5350 static const float quad2[] =
5352 -1.0f, 0.0f, 0.1f,
5353 -1.0f, 1.0f, 0.1f,
5354 0.0f, 0.0f, 0.1f,
5355 0.0f, 1.0f, 0.1f,
5357 static const float quad3[] =
5359 0.0f, 0.0f, 0.1f, 1.0f,
5360 0.0f, 1.0f, 0.1f, 1.0f,
5361 1.0f, 0.0f, 0.1f, 1.0f,
5362 1.0f, 1.0f, 0.1f, 1.0f,
5364 static const D3DMATRIX mat =
5366 0.0f, 0.0f, 0.0f, 0.0f,
5367 0.0f, 0.0f, 0.0f, 0.0f,
5368 0.0f, 0.0f, 0.0f, 0.0f,
5369 0.0f, 1.0f, 0.0f, 0.0f,
5370 }}};
5371 static const D3DMATRIX mat2 =
5373 0.0f, 0.0f, 0.0f, 1.0f,
5374 1.0f, 0.0f, 0.0f, 0.0f,
5375 0.0f, 1.0f, 0.0f, 0.0f,
5376 0.0f, 0.0f, 1.0f, 0.0f,
5377 }}};
5378 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5379 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5381 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5382 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5383 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5384 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5385 * 4th *input* coordinate.
5387 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5388 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5389 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5390 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5392 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5394 /* None passed */
5395 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5396 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5397 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5398 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5400 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5402 /* 4 used, 1 passed */
5403 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5404 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5405 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5406 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5408 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5410 hr = IDirect3DDevice9_EndScene(device);
5411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5413 color = getPixelColor(device, 160, 360);
5414 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5415 color = getPixelColor(device, 160, 120);
5416 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5417 color = getPixelColor(device, 480, 120);
5418 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5419 /* Quad4: unused */
5421 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5424 IDirect3DVolumeTexture9_Release(volume);
5426 out:
5427 IDirect3DVertexDeclaration9_Release(decl);
5428 IDirect3DVertexDeclaration9_Release(decl2);
5429 IDirect3DVertexDeclaration9_Release(decl3);
5430 IDirect3DVertexDeclaration9_Release(decl4);
5431 refcount = IDirect3DDevice9_Release(device);
5432 ok(!refcount, "Device has %u references left.\n", refcount);
5433 done:
5434 IDirect3D9_Release(d3d);
5435 DestroyWindow(window);
5438 static void texdepth_test(void)
5440 IDirect3DPixelShader9 *shader;
5441 IDirect3DDevice9 *device;
5442 IDirect3D9 *d3d;
5443 ULONG refcount;
5444 D3DCAPS9 caps;
5445 DWORD color;
5446 HWND window;
5447 HRESULT hr;
5449 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5450 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5451 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5452 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5453 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5454 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5455 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5456 static const DWORD shader_code[] =
5458 0xffff0104, /* ps_1_4 */
5459 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5460 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5461 0x0000fffd, /* phase */
5462 0x00000057, 0x800f0005, /* texdepth r5 */
5463 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5464 0x0000ffff /* end */
5466 static const float vertex[] =
5468 -1.0f, -1.0f, 0.0f,
5469 -1.0f, 1.0f, 0.0f,
5470 1.0f, -1.0f, 1.0f,
5471 1.0f, 1.0f, 1.0f,
5474 window = create_window();
5475 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5476 ok(!!d3d, "Failed to create a D3D object.\n");
5477 if (!(device = create_device(d3d, window, window, TRUE)))
5479 skip("Failed to create a D3D device, skipping tests.\n");
5480 goto done;
5483 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5484 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5485 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5487 skip("No ps_1_4 support, skipping tests.\n");
5488 IDirect3DDevice9_Release(device);
5489 goto done;
5492 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5493 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5495 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5496 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5498 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5500 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5502 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5504 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5505 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5506 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5508 /* Fill the depth buffer with a gradient */
5509 hr = IDirect3DDevice9_BeginScene(device);
5510 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5511 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5512 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5513 hr = IDirect3DDevice9_EndScene(device);
5514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5516 /* Now perform the actual tests. Same geometry, but with the shader */
5517 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5521 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5524 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5526 hr = IDirect3DDevice9_BeginScene(device);
5527 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5529 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5530 hr = IDirect3DDevice9_EndScene(device);
5531 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5533 color = getPixelColor(device, 158, 240);
5534 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5535 color = getPixelColor(device, 162, 240);
5536 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5538 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5539 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5541 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5542 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5544 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5545 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5546 hr = IDirect3DDevice9_BeginScene(device);
5547 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5548 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5549 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5550 hr = IDirect3DDevice9_EndScene(device);
5551 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5553 color = getPixelColor(device, 318, 240);
5554 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5555 color = getPixelColor(device, 322, 240);
5556 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5558 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5559 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5561 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5562 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5564 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5565 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5566 hr = IDirect3DDevice9_BeginScene(device);
5567 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5569 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5570 hr = IDirect3DDevice9_EndScene(device);
5571 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5573 color = getPixelColor(device, 1, 240);
5574 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5577 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5580 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5582 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5583 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5584 hr = IDirect3DDevice9_BeginScene(device);
5585 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5587 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5588 hr = IDirect3DDevice9_EndScene(device);
5589 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5591 color = getPixelColor(device, 318, 240);
5592 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5593 color = getPixelColor(device, 322, 240);
5594 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5597 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5599 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5600 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5602 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5603 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5604 hr = IDirect3DDevice9_BeginScene(device);
5605 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5607 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5608 hr = IDirect3DDevice9_EndScene(device);
5609 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5611 color = getPixelColor(device, 1, 240);
5612 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5614 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5615 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5618 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5620 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5621 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5622 hr = IDirect3DDevice9_BeginScene(device);
5623 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5625 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5626 hr = IDirect3DDevice9_EndScene(device);
5627 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5629 color = getPixelColor(device, 638, 240);
5630 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5632 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5636 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5638 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5639 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5640 hr = IDirect3DDevice9_BeginScene(device);
5641 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5643 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5644 hr = IDirect3DDevice9_EndScene(device);
5645 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5647 color = getPixelColor(device, 638, 240);
5648 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5650 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5651 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5653 IDirect3DPixelShader9_Release(shader);
5654 refcount = IDirect3DDevice9_Release(device);
5655 ok(!refcount, "Device has %u references left.\n", refcount);
5656 done:
5657 IDirect3D9_Release(d3d);
5658 DestroyWindow(window);
5661 static void texkill_test(void)
5663 IDirect3DPixelShader9 *shader;
5664 IDirect3DDevice9 *device;
5665 IDirect3D9 *d3d;
5666 ULONG refcount;
5667 D3DCAPS9 caps;
5668 DWORD color;
5669 HWND window;
5670 HRESULT hr;
5672 static const float vertex[] =
5674 /* bottom top right left */
5675 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5676 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5677 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5678 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5680 static const DWORD shader_code_11[] =
5682 0xffff0101, /* ps_1_1 */
5683 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5684 0x00000041, 0xb00f0000, /* texkill t0 */
5685 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5686 0x0000ffff /* end */
5688 static const DWORD shader_code_20[] =
5690 0xffff0200, /* ps_2_0 */
5691 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5692 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5693 0x01000041, 0xb00f0000, /* texkill t0 */
5694 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5695 0x0000ffff /* end */
5698 window = create_window();
5699 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5700 ok(!!d3d, "Failed to create a D3D object.\n");
5701 if (!(device = create_device(d3d, window, window, TRUE)))
5703 skip("Failed to create a D3D device, skipping tests.\n");
5704 goto done;
5707 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5708 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5709 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5711 skip("No ps_1_1 support, skipping tests.\n");
5712 IDirect3DDevice9_Release(device);
5713 goto done;
5716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5717 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5718 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5719 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5721 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5722 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5723 hr = IDirect3DDevice9_BeginScene(device);
5724 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5725 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5726 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5728 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5729 hr = IDirect3DDevice9_EndScene(device);
5730 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5732 color = getPixelColor(device, 63, 46);
5733 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5734 color = getPixelColor(device, 66, 46);
5735 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5736 color = getPixelColor(device, 63, 49);
5737 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5738 color = getPixelColor(device, 66, 49);
5739 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5741 color = getPixelColor(device, 578, 46);
5742 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5743 color = getPixelColor(device, 575, 46);
5744 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5745 color = getPixelColor(device, 578, 49);
5746 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5747 color = getPixelColor(device, 575, 49);
5748 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5750 color = getPixelColor(device, 63, 430);
5751 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5752 color = getPixelColor(device, 63, 433);
5753 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5754 color = getPixelColor(device, 66, 433);
5755 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5756 color = getPixelColor(device, 66, 430);
5757 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5759 color = getPixelColor(device, 578, 430);
5760 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5761 color = getPixelColor(device, 578, 433);
5762 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5763 color = getPixelColor(device, 575, 433);
5764 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5765 color = getPixelColor(device, 575, 430);
5766 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5768 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5771 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5773 IDirect3DPixelShader9_Release(shader);
5775 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5777 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5779 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5780 IDirect3DDevice9_Release(device);
5781 goto done;
5784 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5785 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5786 hr = IDirect3DDevice9_BeginScene(device);
5787 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5789 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5790 hr = IDirect3DDevice9_EndScene(device);
5791 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5793 color = getPixelColor(device, 63, 46);
5794 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5795 color = getPixelColor(device, 66, 46);
5796 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5797 color = getPixelColor(device, 63, 49);
5798 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5799 color = getPixelColor(device, 66, 49);
5800 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5802 color = getPixelColor(device, 578, 46);
5803 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5804 color = getPixelColor(device, 575, 46);
5805 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5806 color = getPixelColor(device, 578, 49);
5807 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5808 color = getPixelColor(device, 575, 49);
5809 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5811 color = getPixelColor(device, 63, 430);
5812 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5813 color = getPixelColor(device, 63, 433);
5814 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5815 color = getPixelColor(device, 66, 433);
5816 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5817 color = getPixelColor(device, 66, 430);
5818 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5820 color = getPixelColor(device, 578, 430);
5821 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5822 color = getPixelColor(device, 578, 433);
5823 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5824 color = getPixelColor(device, 575, 433);
5825 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5826 color = getPixelColor(device, 575, 430);
5827 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5829 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5830 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5832 IDirect3DPixelShader9_Release(shader);
5833 refcount = IDirect3DDevice9_Release(device);
5834 ok(!refcount, "Device has %u references left.\n", refcount);
5835 done:
5836 IDirect3D9_Release(d3d);
5837 DestroyWindow(window);
5840 static void autogen_mipmap_test(void)
5842 IDirect3DTexture9 *texture = NULL;
5843 IDirect3DSurface9 *surface;
5844 IDirect3DDevice9 *device;
5845 unsigned int x, y;
5846 D3DLOCKED_RECT lr;
5847 IDirect3D9 *d3d;
5848 D3DCOLOR color;
5849 ULONG refcount;
5850 HWND window;
5851 HRESULT hr;
5853 static const RECT r1 = {256, 256, 512, 512};
5854 static const RECT r2 = {512, 256, 768, 512};
5855 static const RECT r3 = {256, 512, 512, 768};
5856 static const RECT r4 = {512, 512, 768, 768};
5857 static const float quad[] =
5859 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5860 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5861 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5862 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5865 window = create_window();
5866 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5867 ok(!!d3d, "Failed to create a D3D object.\n");
5868 if (!(device = create_device(d3d, window, window, TRUE)))
5870 skip("Failed to create a D3D device, skipping tests.\n");
5871 goto done;
5874 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5875 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5877 skip("No autogenmipmap support.\n");
5878 IDirect3DDevice9_Release(device);
5879 goto done;
5882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5883 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5885 /* Make the mipmap big, so that a smaller mipmap is used
5887 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5888 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5889 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5891 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5892 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5893 memset(&lr, 0, sizeof(lr));
5894 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5895 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5896 for(y = 0; y < 1024; y++) {
5897 for(x = 0; x < 1024; x++) {
5898 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5899 POINT pt;
5901 pt.x = x;
5902 pt.y = y;
5903 if(PtInRect(&r1, pt)) {
5904 *dst = 0xffff0000;
5905 } else if(PtInRect(&r2, pt)) {
5906 *dst = 0xff00ff00;
5907 } else if(PtInRect(&r3, pt)) {
5908 *dst = 0xff0000ff;
5909 } else if(PtInRect(&r4, pt)) {
5910 *dst = 0xff000000;
5911 } else {
5912 *dst = 0xffffffff;
5916 hr = IDirect3DSurface9_UnlockRect(surface);
5917 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5918 IDirect3DSurface9_Release(surface);
5920 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5921 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5922 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5923 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5925 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5927 hr = IDirect3DDevice9_BeginScene(device);
5928 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5929 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5930 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5932 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5933 hr = IDirect3DDevice9_EndScene(device);
5934 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5935 IDirect3DTexture9_Release(texture);
5937 color = getPixelColor(device, 200, 200);
5938 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5939 color = getPixelColor(device, 280, 200);
5940 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5941 color = getPixelColor(device, 360, 200);
5942 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5943 color = getPixelColor(device, 440, 200);
5944 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5945 color = getPixelColor(device, 200, 270);
5946 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5947 color = getPixelColor(device, 280, 270);
5948 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5949 color = getPixelColor(device, 360, 270);
5950 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5951 color = getPixelColor(device, 440, 270);
5952 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5953 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5956 refcount = IDirect3DDevice9_Release(device);
5957 ok(!refcount, "Device has %u references left.\n", refcount);
5958 done:
5959 IDirect3D9_Release(d3d);
5960 DestroyWindow(window);
5963 static void test_constant_clamp_vs(void)
5965 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5966 IDirect3DVertexDeclaration9 *decl;
5967 IDirect3DDevice9 *device;
5968 IDirect3D9 *d3d;
5969 D3DCOLOR color;
5970 ULONG refcount;
5971 D3DCAPS9 caps;
5972 HWND window;
5973 HRESULT hr;
5975 static const DWORD shader_code_11[] =
5977 0xfffe0101, /* vs_1_1 */
5978 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5979 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5980 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5981 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5982 0x0000ffff /* end */
5984 static const DWORD shader_code_11_2[] =
5986 0xfffe0101, /* vs_1_1 */
5987 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5988 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5989 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5990 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5991 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5992 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5993 0x0000ffff /* end */
5995 static const DWORD shader_code_20[] =
5997 0xfffe0200, /* vs_2_0 */
5998 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5999 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6000 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6001 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6002 0x0000ffff /* end */
6004 static const DWORD shader_code_20_2[] =
6006 0xfffe0200, /* vs_2_0 */
6007 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6008 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6009 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6010 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6011 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6012 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6013 0x0000ffff /* end */
6015 static const D3DVERTEXELEMENT9 decl_elements[] =
6017 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6018 D3DDECL_END()
6020 static const float quad1[] =
6022 -1.0f, -1.0f, 0.1f,
6023 -1.0f, 0.0f, 0.1f,
6024 0.0f, -1.0f, 0.1f,
6025 0.0f, 0.0f, 0.1f,
6027 static const float quad2[] =
6029 0.0f, -1.0f, 0.1f,
6030 0.0f, 0.0f, 0.1f,
6031 1.0f, -1.0f, 0.1f,
6032 1.0f, 0.0f, 0.1f,
6034 static const float quad3[] =
6036 0.0f, 0.0f, 0.1f,
6037 0.0f, 1.0f, 0.1f,
6038 1.0f, 0.0f, 0.1f,
6039 1.0f, 1.0f, 0.1f,
6041 static const float quad4[] =
6043 -1.0f, 0.0f, 0.1f,
6044 -1.0f, 1.0f, 0.1f,
6045 0.0f, 0.0f, 0.1f,
6046 0.0f, 1.0f, 0.1f,
6048 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6049 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6051 window = create_window();
6052 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6053 ok(!!d3d, "Failed to create a D3D object.\n");
6054 if (!(device = create_device(d3d, window, window, TRUE)))
6056 skip("Failed to create a D3D device, skipping tests.\n");
6057 goto done;
6060 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6061 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6062 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6064 skip("No vs_1_1 support, skipping tests.\n");
6065 IDirect3DDevice9_Release(device);
6066 goto done;
6069 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6070 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6072 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6073 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6074 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6075 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6076 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6077 if(FAILED(hr)) shader_20 = NULL;
6078 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6079 if(FAILED(hr)) shader_20_2 = NULL;
6080 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6081 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6083 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6084 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6085 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6086 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6087 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6088 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6090 hr = IDirect3DDevice9_BeginScene(device);
6091 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6093 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6094 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6096 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6098 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6099 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6101 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6103 if (shader_20)
6105 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6106 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6107 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6108 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6111 if (shader_20_2)
6113 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6114 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6115 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6116 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6119 hr = IDirect3DDevice9_EndScene(device);
6120 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6122 color = getPixelColor(device, 160, 360);
6123 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6124 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6125 color = getPixelColor(device, 480, 360);
6126 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6127 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6128 if(shader_20) {
6129 color = getPixelColor(device, 480, 120);
6130 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6131 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6133 if(shader_20_2) {
6134 color = getPixelColor(device, 160, 120);
6135 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6136 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6138 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6139 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6141 IDirect3DVertexDeclaration9_Release(decl);
6142 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6143 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6144 IDirect3DVertexShader9_Release(shader_11_2);
6145 IDirect3DVertexShader9_Release(shader_11);
6146 refcount = IDirect3DDevice9_Release(device);
6147 ok(!refcount, "Device has %u references left.\n", refcount);
6148 done:
6149 IDirect3D9_Release(d3d);
6150 DestroyWindow(window);
6153 static void constant_clamp_ps_test(void)
6155 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6156 IDirect3DDevice9 *device;
6157 IDirect3D9 *d3d;
6158 ULONG refcount;
6159 D3DCAPS9 caps;
6160 DWORD color;
6161 HWND window;
6162 HRESULT hr;
6164 static const DWORD shader_code_11[] =
6166 0xffff0101, /* ps_1_1 */
6167 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6168 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6169 0x0000ffff /* end */
6171 static const DWORD shader_code_12[] =
6173 0xffff0102, /* ps_1_2 */
6174 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6175 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6176 0x0000ffff /* end */
6178 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6179 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6180 * unlikely that 1.3 shaders are different. During development of this
6181 * test, 1.3 shaders were verified too. */
6182 static const DWORD shader_code_14[] =
6184 0xffff0104, /* ps_1_4 */
6185 /* Try to make one constant local. It gets clamped too, although the
6186 * binary contains the bigger numbers. */
6187 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6188 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6189 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6190 0x0000ffff /* end */
6192 static const DWORD shader_code_20[] =
6194 0xffff0200, /* ps_2_0 */
6195 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6196 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6197 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6198 0x0000ffff /* end */
6200 static const float quad1[] =
6202 -1.0f, -1.0f, 0.1f,
6203 -1.0f, 0.0f, 0.1f,
6204 0.0f, -1.0f, 0.1f,
6205 0.0f, 0.0f, 0.1f,
6207 static const float quad2[] =
6209 0.0f, -1.0f, 0.1f,
6210 0.0f, 0.0f, 0.1f,
6211 1.0f, -1.0f, 0.1f,
6212 1.0f, 0.0f, 0.1f,
6214 static const float quad3[] =
6216 0.0f, 0.0f, 0.1f,
6217 0.0f, 1.0f, 0.1f,
6218 1.0f, 0.0f, 0.1f,
6219 1.0f, 1.0f, 0.1f,
6221 static const float quad4[] =
6223 -1.0f, 0.0f, 0.1f,
6224 -1.0f, 1.0f, 0.1f,
6225 0.0f, 0.0f, 0.1f,
6226 0.0f, 1.0f, 0.1f,
6228 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6229 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6231 window = create_window();
6232 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6233 ok(!!d3d, "Failed to create a D3D object.\n");
6234 if (!(device = create_device(d3d, window, window, TRUE)))
6236 skip("Failed to create a D3D device, skipping tests.\n");
6237 goto done;
6240 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6241 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6242 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6244 skip("No ps_1_4 support, skipping tests.\n");
6245 IDirect3DDevice9_Release(device);
6246 goto done;
6249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6250 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6252 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6253 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6254 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6255 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6256 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6257 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6258 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6259 if(FAILED(hr)) shader_20 = NULL;
6261 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6262 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6263 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6264 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6265 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6266 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6268 hr = IDirect3DDevice9_BeginScene(device);
6269 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6271 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6272 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6274 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6276 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6277 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6279 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6281 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6282 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6284 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6286 if (shader_20)
6288 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6289 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6290 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6291 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6294 hr = IDirect3DDevice9_EndScene(device);
6295 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6297 color = getPixelColor(device, 160, 360);
6298 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6299 "quad 1 has color %08x, expected 0x00808000\n", color);
6300 color = getPixelColor(device, 480, 360);
6301 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6302 "quad 2 has color %08x, expected 0x00808000\n", color);
6303 color = getPixelColor(device, 480, 120);
6304 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6305 "quad 3 has color %08x, expected 0x00808000\n", color);
6306 if(shader_20) {
6307 color = getPixelColor(device, 160, 120);
6308 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6309 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6311 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6312 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6314 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6315 IDirect3DPixelShader9_Release(shader_14);
6316 IDirect3DPixelShader9_Release(shader_12);
6317 IDirect3DPixelShader9_Release(shader_11);
6318 refcount = IDirect3DDevice9_Release(device);
6319 ok(!refcount, "Device has %u references left.\n", refcount);
6320 done:
6321 IDirect3D9_Release(d3d);
6322 DestroyWindow(window);
6325 static void dp2add_ps_test(void)
6327 IDirect3DPixelShader9 *shader_dp2add_sat;
6328 IDirect3DPixelShader9 *shader_dp2add;
6329 IDirect3DDevice9 *device;
6330 IDirect3D9 *d3d;
6331 ULONG refcount;
6332 D3DCAPS9 caps;
6333 DWORD color;
6334 HWND window;
6335 HRESULT hr;
6337 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6338 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6339 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6340 * r0 first.
6341 * The result here for the r,g,b components should be roughly 0.5:
6342 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6343 static const DWORD shader_code_dp2add[] = {
6344 0xffff0200, /* ps_2_0 */
6345 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6347 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6348 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6350 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6351 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6352 0x0000ffff /* end */
6355 /* Test the _sat modifier, too. Result here should be:
6356 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6357 * _SAT: ==> 1.0
6358 * ADD: (1.0 + -0.5) = 0.5
6360 static const DWORD shader_code_dp2add_sat[] = {
6361 0xffff0200, /* ps_2_0 */
6362 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6364 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6365 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6366 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6368 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6369 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6370 0x0000ffff /* end */
6372 static const float quad[] =
6374 -1.0f, -1.0f, 0.1f,
6375 -1.0f, 1.0f, 0.1f,
6376 1.0f, -1.0f, 0.1f,
6377 1.0f, 1.0f, 0.1f,
6380 window = create_window();
6381 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6382 ok(!!d3d, "Failed to create a D3D object.\n");
6383 if (!(device = create_device(d3d, window, window, TRUE)))
6385 skip("Failed to create a D3D device, skipping tests.\n");
6386 goto done;
6389 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6390 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6391 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6393 skip("No ps_2_0 support, skipping tests.\n");
6394 IDirect3DDevice9_Release(device);
6395 goto done;
6398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6401 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6404 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6405 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6407 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6408 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6410 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6411 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6412 hr = IDirect3DDevice9_BeginScene(device);
6413 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6415 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6416 hr = IDirect3DDevice9_EndScene(device);
6417 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6419 color = getPixelColor(device, 360, 240);
6420 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6422 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6423 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6424 IDirect3DPixelShader9_Release(shader_dp2add);
6426 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6427 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6428 hr = IDirect3DDevice9_BeginScene(device);
6429 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6431 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6432 hr = IDirect3DDevice9_EndScene(device);
6433 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6435 color = getPixelColor(device, 360, 240);
6436 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6438 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6439 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6440 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6442 refcount = IDirect3DDevice9_Release(device);
6443 ok(!refcount, "Device has %u references left.\n", refcount);
6444 done:
6445 IDirect3D9_Release(d3d);
6446 DestroyWindow(window);
6449 static void cnd_test(void)
6451 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6452 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6453 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6454 IDirect3DDevice9 *device;
6455 IDirect3D9 *d3d;
6456 ULONG refcount;
6457 D3DCAPS9 caps;
6458 HWND window;
6459 DWORD color;
6460 HRESULT hr;
6462 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6463 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6464 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6465 * in 1.x pixel shaders. */
6466 static const DWORD shader_code_11[] =
6468 0xffff0101, /* ps_1_1 */
6469 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6470 0x00000040, 0xb00f0000, /* texcoord t0 */
6471 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6472 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6473 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6474 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6475 0x0000ffff /* end */
6477 static const DWORD shader_code_12[] =
6479 0xffff0102, /* ps_1_2 */
6480 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6481 0x00000040, 0xb00f0000, /* texcoord t0 */
6482 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6483 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6484 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6485 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6486 0x0000ffff /* end */
6488 static const DWORD shader_code_13[] =
6490 0xffff0103, /* ps_1_3 */
6491 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6492 0x00000040, 0xb00f0000, /* texcoord t0 */
6493 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6494 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6495 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6496 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6497 0x0000ffff /* end */
6499 static const DWORD shader_code_14[] =
6501 0xffff0104, /* ps_1_3 */
6502 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6503 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6504 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6505 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6506 0x0000ffff /* end */
6509 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6510 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6511 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6512 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6513 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6514 * well enough.
6516 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6517 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6518 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6519 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6521 static const DWORD shader_code_11_coissue[] =
6523 0xffff0101, /* ps_1_1 */
6524 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6525 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6526 0x00000040, 0xb00f0000, /* texcoord t0 */
6527 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6528 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6529 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6530 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6531 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6532 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6533 0x0000ffff /* end */
6535 static const DWORD shader_code_11_coissue_2[] =
6537 0xffff0101, /* ps_1_1 */
6538 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6539 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6540 0x00000040, 0xb00f0000, /* texcoord t0 */
6541 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6542 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6543 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6544 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6545 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6546 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6547 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6548 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6549 0x0000ffff /* end */
6551 static const DWORD shader_code_12_coissue[] =
6553 0xffff0102, /* ps_1_2 */
6554 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6555 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6556 0x00000040, 0xb00f0000, /* texcoord t0 */
6557 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6558 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6559 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6560 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6561 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6562 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6563 0x0000ffff /* end */
6565 static const DWORD shader_code_12_coissue_2[] =
6567 0xffff0102, /* ps_1_2 */
6568 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6569 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6570 0x00000040, 0xb00f0000, /* texcoord t0 */
6571 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6572 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6573 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6574 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6575 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6576 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6577 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6578 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6579 0x0000ffff /* end */
6581 static const DWORD shader_code_13_coissue[] =
6583 0xffff0103, /* ps_1_3 */
6584 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6585 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6586 0x00000040, 0xb00f0000, /* texcoord t0 */
6587 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6588 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6589 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6590 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6591 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6592 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6593 0x0000ffff /* end */
6595 static const DWORD shader_code_13_coissue_2[] =
6597 0xffff0103, /* ps_1_3 */
6598 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6599 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6600 0x00000040, 0xb00f0000, /* texcoord t0 */
6601 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6602 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6603 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6604 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6605 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6606 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6607 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6608 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6609 0x0000ffff /* end */
6611 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6612 * texcrd result to cnd, it will compare against 0.5. */
6613 static const DWORD shader_code_14_coissue[] =
6615 0xffff0104, /* ps_1_4 */
6616 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6617 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6618 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6619 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6620 0x0000ffff /* end */
6622 static const DWORD shader_code_14_coissue_2[] =
6624 0xffff0104, /* ps_1_4 */
6625 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6626 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6627 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6628 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6629 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6630 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6631 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6632 0x0000ffff /* end */
6634 static const float quad1[] =
6636 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6637 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6638 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6639 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6641 static const float quad2[] =
6643 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6644 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6645 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6646 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6648 static const float quad3[] =
6650 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6651 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6652 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6653 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6655 static const float quad4[] =
6657 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6658 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6659 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6660 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6662 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6663 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6664 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6665 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6667 window = create_window();
6668 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6669 ok(!!d3d, "Failed to create a D3D object.\n");
6670 if (!(device = create_device(d3d, window, window, TRUE)))
6672 skip("Failed to create a D3D device, skipping tests.\n");
6673 goto done;
6676 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6677 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6678 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6680 skip("No ps_1_4 support, skipping tests.\n");
6681 IDirect3DDevice9_Release(device);
6682 goto done;
6685 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6686 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6688 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6689 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6690 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6692 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6693 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6694 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6695 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6696 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6697 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6698 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6700 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6701 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6702 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6703 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6704 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6705 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6706 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6707 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6708 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6709 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6710 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6711 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6713 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6715 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6716 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6717 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6718 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6720 hr = IDirect3DDevice9_BeginScene(device);
6721 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6723 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6724 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6726 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6728 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6729 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6731 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6733 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6734 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6736 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6738 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6739 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6741 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6743 hr = IDirect3DDevice9_EndScene(device);
6744 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6746 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6747 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6749 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6750 color = getPixelColor(device, 158, 118);
6751 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6752 color = getPixelColor(device, 162, 118);
6753 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6754 color = getPixelColor(device, 158, 122);
6755 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6756 color = getPixelColor(device, 162, 122);
6757 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6759 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6760 color = getPixelColor(device, 158, 358);
6761 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6762 color = getPixelColor(device, 162, 358);
6763 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6764 color = getPixelColor(device, 158, 362);
6765 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6766 color = getPixelColor(device, 162, 362);
6767 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6769 /* 1.2 shader */
6770 color = getPixelColor(device, 478, 358);
6771 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6772 color = getPixelColor(device, 482, 358);
6773 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6774 color = getPixelColor(device, 478, 362);
6775 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6776 color = getPixelColor(device, 482, 362);
6777 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6779 /* 1.3 shader */
6780 color = getPixelColor(device, 478, 118);
6781 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6782 color = getPixelColor(device, 482, 118);
6783 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6784 color = getPixelColor(device, 478, 122);
6785 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6786 color = getPixelColor(device, 482, 122);
6787 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6789 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6790 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6792 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6793 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6794 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6795 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6796 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6797 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6799 hr = IDirect3DDevice9_BeginScene(device);
6800 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6802 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6803 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6805 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6807 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6808 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6810 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6812 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6813 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6815 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6817 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6818 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6819 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6820 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6822 hr = IDirect3DDevice9_EndScene(device);
6823 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6825 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6826 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6828 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6829 * that we swapped the values in c1 and c2 to make the other tests return some color
6831 color = getPixelColor(device, 158, 118);
6832 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6833 color = getPixelColor(device, 162, 118);
6834 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6835 color = getPixelColor(device, 158, 122);
6836 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6837 color = getPixelColor(device, 162, 122);
6838 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6840 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6841 * (The Win7 nvidia driver always selects c2)
6843 color = getPixelColor(device, 158, 358);
6844 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6845 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6846 color = getPixelColor(device, 162, 358);
6847 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6848 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6849 color = getPixelColor(device, 158, 362);
6850 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6851 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6852 color = getPixelColor(device, 162, 362);
6853 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6854 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6856 /* 1.2 shader */
6857 color = getPixelColor(device, 478, 358);
6858 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6859 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6860 color = getPixelColor(device, 482, 358);
6861 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6862 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6863 color = getPixelColor(device, 478, 362);
6864 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6865 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6866 color = getPixelColor(device, 482, 362);
6867 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6868 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6870 /* 1.3 shader */
6871 color = getPixelColor(device, 478, 118);
6872 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6873 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6874 color = getPixelColor(device, 482, 118);
6875 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6876 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6877 color = getPixelColor(device, 478, 122);
6878 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6879 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6880 color = getPixelColor(device, 482, 122);
6881 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6882 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6885 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6887 /* Retest with the coissue flag on the alpha instruction instead. This
6888 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6889 * the same as coissue on .rgb. */
6890 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6891 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6893 hr = IDirect3DDevice9_BeginScene(device);
6894 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6896 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6897 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6898 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6899 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6901 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6902 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6903 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6904 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6906 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6907 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6908 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6909 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6911 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6912 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6913 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6914 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6916 hr = IDirect3DDevice9_EndScene(device);
6917 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6919 /* 1.4 shader */
6920 color = getPixelColor(device, 158, 118);
6921 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6922 color = getPixelColor(device, 162, 118);
6923 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6924 color = getPixelColor(device, 158, 122);
6925 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6926 color = getPixelColor(device, 162, 122);
6927 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6929 /* 1.1 shader */
6930 color = getPixelColor(device, 238, 358);
6931 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6932 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6933 color = getPixelColor(device, 242, 358);
6934 ok(color_match(color, 0x00000000, 1),
6935 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6936 color = getPixelColor(device, 238, 362);
6937 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6938 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6939 color = getPixelColor(device, 242, 362);
6940 ok(color_match(color, 0x00000000, 1),
6941 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6943 /* 1.2 shader */
6944 color = getPixelColor(device, 558, 358);
6945 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6946 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6947 color = getPixelColor(device, 562, 358);
6948 ok(color_match(color, 0x00000000, 1),
6949 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6950 color = getPixelColor(device, 558, 362);
6951 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6952 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6953 color = getPixelColor(device, 562, 362);
6954 ok(color_match(color, 0x00000000, 1),
6955 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6957 /* 1.3 shader */
6958 color = getPixelColor(device, 558, 118);
6959 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6960 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6961 color = getPixelColor(device, 562, 118);
6962 ok(color_match(color, 0x00000000, 1),
6963 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6964 color = getPixelColor(device, 558, 122);
6965 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6966 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6967 color = getPixelColor(device, 562, 122);
6968 ok(color_match(color, 0x00000000, 1),
6969 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6971 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6972 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6974 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6975 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6976 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6977 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6978 IDirect3DPixelShader9_Release(shader_14_coissue);
6979 IDirect3DPixelShader9_Release(shader_13_coissue);
6980 IDirect3DPixelShader9_Release(shader_12_coissue);
6981 IDirect3DPixelShader9_Release(shader_11_coissue);
6982 IDirect3DPixelShader9_Release(shader_14);
6983 IDirect3DPixelShader9_Release(shader_13);
6984 IDirect3DPixelShader9_Release(shader_12);
6985 IDirect3DPixelShader9_Release(shader_11);
6986 refcount = IDirect3DDevice9_Release(device);
6987 ok(!refcount, "Device has %u references left.\n", refcount);
6988 done:
6989 IDirect3D9_Release(d3d);
6990 DestroyWindow(window);
6993 static void nested_loop_test(void)
6995 IDirect3DVertexShader9 *vshader;
6996 IDirect3DPixelShader9 *shader;
6997 IDirect3DDevice9 *device;
6998 IDirect3D9 *d3d;
6999 ULONG refcount;
7000 D3DCAPS9 caps;
7001 DWORD color;
7002 HWND window;
7003 HRESULT hr;
7005 static const DWORD shader_code[] =
7007 0xffff0300, /* ps_3_0 */
7008 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7009 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7010 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7011 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7012 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7013 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7014 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7015 0x0000001d, /* endloop */
7016 0x0000001d, /* endloop */
7017 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7018 0x0000ffff /* end */
7020 static const DWORD vshader_code[] =
7022 0xfffe0300, /* vs_3_0 */
7023 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7024 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7025 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7026 0x0000ffff /* end */
7028 static const float quad[] =
7030 -1.0f, -1.0f, 0.1f,
7031 -1.0f, 1.0f, 0.1f,
7032 1.0f, -1.0f, 0.1f,
7033 1.0f, 1.0f, 0.1f,
7036 window = create_window();
7037 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7038 ok(!!d3d, "Failed to create a D3D object.\n");
7039 if (!(device = create_device(d3d, window, window, TRUE)))
7041 skip("Failed to create a D3D device, skipping tests.\n");
7042 goto done;
7045 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7046 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7047 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7049 skip("No shader model 3 support, skipping tests.\n");
7050 IDirect3DDevice9_Release(device);
7051 goto done;
7054 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7055 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7056 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7057 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7058 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7059 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7060 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7062 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7063 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7065 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7067 hr = IDirect3DDevice9_BeginScene(device);
7068 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7070 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7071 hr = IDirect3DDevice9_EndScene(device);
7072 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7074 color = getPixelColor(device, 360, 240);
7075 ok(color_match(color, 0x00800000, 1),
7076 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7078 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7079 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7081 IDirect3DPixelShader9_Release(shader);
7082 IDirect3DVertexShader9_Release(vshader);
7083 refcount = IDirect3DDevice9_Release(device);
7084 ok(!refcount, "Device has %u references left.\n", refcount);
7085 done:
7086 IDirect3D9_Release(d3d);
7087 DestroyWindow(window);
7090 static void pretransformed_varying_test(void)
7092 /* dcl_position: fails to compile */
7093 static const DWORD blendweight_code[] =
7095 0xffff0300, /* ps_3_0 */
7096 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7097 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7098 0x0000ffff /* end */
7100 static const DWORD blendindices_code[] =
7102 0xffff0300, /* ps_3_0 */
7103 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7104 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7105 0x0000ffff /* end */
7107 static const DWORD normal_code[] =
7109 0xffff0300, /* ps_3_0 */
7110 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7111 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7112 0x0000ffff /* end */
7114 /* psize: fails? */
7115 static const DWORD texcoord0_code[] =
7117 0xffff0300, /* ps_3_0 */
7118 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7119 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7120 0x0000ffff /* end */
7122 static const DWORD tangent_code[] =
7124 0xffff0300, /* ps_3_0 */
7125 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7126 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7127 0x0000ffff /* end */
7129 static const DWORD binormal_code[] =
7131 0xffff0300, /* ps_3_0 */
7132 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7133 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7134 0x0000ffff /* end */
7136 /* tessfactor: fails */
7137 /* positiont: fails */
7138 static const DWORD color_code[] =
7140 0xffff0300, /* ps_3_0 */
7141 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7142 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7143 0x0000ffff /* end */
7145 static const DWORD fog_code[] =
7147 0xffff0300, /* ps_3_0 */
7148 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7149 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7150 0x0000ffff /* end */
7152 static const DWORD depth_code[] =
7154 0xffff0300, /* ps_3_0 */
7155 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7156 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7157 0x0000ffff /* end */
7159 static const DWORD specular_code[] =
7161 0xffff0300, /* ps_3_0 */
7162 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7163 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7164 0x0000ffff /* end */
7166 /* sample: fails */
7167 static const DWORD texcoord1_code[] =
7169 0xffff0300, /* ps_3_0 */
7170 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7171 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7172 0x0000ffff /* end */
7174 static const DWORD texcoord1_alpha_code[] =
7176 0xffff0300, /* ps_3_0 */
7177 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7178 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7179 0x0000ffff /* end */
7182 static const struct
7184 const char *name;
7185 const DWORD *shader_code;
7186 DWORD color;
7187 BOOL todo;
7188 BOOL broken_warp;
7190 tests[] =
7192 {"blendweight", blendweight_code, 0x00191919, TRUE },
7193 {"blendindices", blendindices_code, 0x00333333, TRUE },
7194 {"normal", normal_code, 0x004c4c4c, TRUE },
7195 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7196 {"tangent", tangent_code, 0x00999999, TRUE },
7197 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7198 {"color", color_code, 0x00e6e6e6, FALSE},
7199 {"fog", fog_code, 0x00666666, TRUE },
7200 {"depth", depth_code, 0x00cccccc, TRUE },
7201 {"specular", specular_code, 0x004488ff, FALSE},
7202 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7203 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE},
7205 /* Declare a monster vertex type :-) */
7206 static const D3DVERTEXELEMENT9 decl_elements[] = {
7207 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7208 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7209 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7210 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7211 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7212 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7213 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7214 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7215 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7216 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7217 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7218 D3DDECL_END()
7221 static const struct
7223 float pos_x, pos_y, pos_z, rhw;
7224 float weight_1, weight_2, weight_3, weight_4;
7225 float index_1, index_2, index_3, index_4;
7226 float normal_1, normal_2, normal_3, normal_4;
7227 float fog_1, fog_2, fog_3, fog_4;
7228 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7229 float tangent_1, tangent_2, tangent_3, tangent_4;
7230 float binormal_1, binormal_2, binormal_3, binormal_4;
7231 float depth_1, depth_2, depth_3, depth_4;
7232 D3DCOLOR diffuse;
7233 D3DCOLOR specular;
7235 data[] =
7238 0.0f, 0.0f, 0.1f, 1.0f,
7239 0.1f, 0.1f, 0.1f, 0.1f,
7240 0.2f, 0.2f, 0.2f, 0.2f,
7241 0.3f, 0.3f, 0.3f, 0.3f,
7242 0.4f, 0.4f, 0.4f, 0.4f,
7243 0.5f, 0.55f, 0.55f, 0.55f,
7244 0.6f, 0.6f, 0.6f, 0.7f,
7245 0.7f, 0.7f, 0.7f, 0.6f,
7246 0.8f, 0.8f, 0.8f, 0.8f,
7247 0xe6e6e6e6, /* 0.9 * 256 */
7248 0x224488ff, /* Nothing special */
7251 640.0f, 0.0f, 0.1f, 1.0f,
7252 0.1f, 0.1f, 0.1f, 0.1f,
7253 0.2f, 0.2f, 0.2f, 0.2f,
7254 0.3f, 0.3f, 0.3f, 0.3f,
7255 0.4f, 0.4f, 0.4f, 0.4f,
7256 0.5f, 0.55f, 0.55f, 0.55f,
7257 0.6f, 0.6f, 0.6f, 0.7f,
7258 0.7f, 0.7f, 0.7f, 0.6f,
7259 0.8f, 0.8f, 0.8f, 0.8f,
7260 0xe6e6e6e6, /* 0.9 * 256 */
7261 0x224488ff, /* Nothing special */
7264 0.0f, 480.0f, 0.1f, 1.0f,
7265 0.1f, 0.1f, 0.1f, 0.1f,
7266 0.2f, 0.2f, 0.2f, 0.2f,
7267 0.3f, 0.3f, 0.3f, 0.3f,
7268 0.4f, 0.4f, 0.4f, 0.4f,
7269 0.5f, 0.55f, 0.55f, 0.55f,
7270 0.6f, 0.6f, 0.6f, 0.7f,
7271 0.7f, 0.7f, 0.7f, 0.6f,
7272 0.8f, 0.8f, 0.8f, 0.8f,
7273 0xe6e6e6e6, /* 0.9 * 256 */
7274 0x224488ff, /* Nothing special */
7277 640.0f, 480.0f, 0.1f, 1.0f,
7278 0.1f, 0.1f, 0.1f, 0.1f,
7279 0.2f, 0.2f, 0.2f, 0.2f,
7280 0.3f, 0.3f, 0.3f, 0.3f,
7281 0.4f, 0.4f, 0.4f, 0.4f,
7282 0.5f, 0.55f, 0.55f, 0.55f,
7283 0.6f, 0.6f, 0.6f, 0.7f,
7284 0.7f, 0.7f, 0.7f, 0.6f,
7285 0.8f, 0.8f, 0.8f, 0.8f,
7286 0xe6e6e6e6, /* 0.9 * 256 */
7287 0x224488ff, /* Nothing special */
7290 D3DADAPTER_IDENTIFIER9 identifier;
7291 IDirect3DVertexDeclaration9 *decl;
7292 IDirect3DDevice9 *device;
7293 IDirect3D9 *d3d;
7294 unsigned int i;
7295 ULONG refcount;
7296 D3DCAPS9 caps;
7297 DWORD color;
7298 HWND window;
7299 HRESULT hr;
7300 BOOL warp;
7302 window = create_window();
7303 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7304 ok(!!d3d, "Failed to create a D3D object.\n");
7305 if (!(device = create_device(d3d, window, window, TRUE)))
7307 skip("Failed to create a D3D device, skipping tests.\n");
7308 goto done;
7311 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7312 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7313 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7315 skip("No shader model 3 support, skipping tests.\n");
7316 IDirect3DDevice9_Release(device);
7317 goto done;
7320 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7321 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7322 warp = adapter_is_warp(&identifier);
7324 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7325 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7326 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7327 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7329 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7331 IDirect3DPixelShader9 *shader;
7333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7334 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7336 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7337 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7339 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7340 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7342 hr = IDirect3DDevice9_BeginScene(device);
7343 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7345 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7346 hr = IDirect3DDevice9_EndScene(device);
7347 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7349 /* This isn't a weekend's job to fix, ignore the problem for now.
7350 * Needs a replacement pipeline. */
7351 color = getPixelColor(device, 360, 240);
7352 if (tests[i].todo)
7353 todo_wine ok(color_match(color, tests[i].color, 1)
7354 || broken(color_match(color, 0x00000000, 1)
7355 && tests[i].shader_code == blendindices_code),
7356 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7357 tests[i].name, color, tests[i].color);
7358 else
7359 ok(color_match(color, tests[i].color, 1) || broken(warp && tests[i].broken_warp),
7360 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7361 tests[i].name, color, tests[i].color);
7363 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7364 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7366 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7367 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7368 IDirect3DPixelShader9_Release(shader);
7371 IDirect3DVertexDeclaration9_Release(decl);
7372 refcount = IDirect3DDevice9_Release(device);
7373 ok(!refcount, "Device has %u references left.\n", refcount);
7374 done:
7375 IDirect3D9_Release(d3d);
7376 DestroyWindow(window);
7379 static void test_compare_instructions(void)
7381 IDirect3DVertexShader9 *shader_slt_scalar;
7382 IDirect3DVertexShader9 *shader_sge_scalar;
7383 IDirect3DVertexShader9 *shader_slt_vec;
7384 IDirect3DVertexShader9 *shader_sge_vec;
7385 IDirect3DDevice9 *device;
7386 IDirect3D9 *d3d;
7387 D3DCOLOR color;
7388 ULONG refcount;
7389 D3DCAPS9 caps;
7390 HWND window;
7391 HRESULT hr;
7393 static const DWORD shader_sge_vec_code[] =
7395 0xfffe0101, /* vs_1_1 */
7396 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7397 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7398 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7399 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7400 0x0000ffff /* end */
7402 static const DWORD shader_slt_vec_code[] =
7404 0xfffe0101, /* vs_1_1 */
7405 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7406 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7407 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7408 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7409 0x0000ffff /* end */
7411 static const DWORD shader_sge_scalar_code[] =
7413 0xfffe0101, /* vs_1_1 */
7414 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7415 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7416 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7417 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7418 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7419 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7420 0x0000ffff /* end */
7422 static const DWORD shader_slt_scalar_code[] =
7424 0xfffe0101, /* vs_1_1 */
7425 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7426 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7427 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7428 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7429 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7430 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7431 0x0000ffff /* end */
7433 static const float quad1[] =
7435 -1.0f, -1.0f, 0.1f,
7436 -1.0f, 0.0f, 0.1f,
7437 0.0f, -1.0f, 0.1f,
7438 0.0f, 0.0f, 0.1f,
7440 static const float quad2[] =
7442 0.0f, -1.0f, 0.1f,
7443 0.0f, 0.0f, 0.1f,
7444 1.0f, -1.0f, 0.1f,
7445 1.0f, 0.0f, 0.1f,
7447 static const float quad3[] =
7449 -1.0f, 0.0f, 0.1f,
7450 -1.0f, 1.0f, 0.1f,
7451 0.0f, 0.0f, 0.1f,
7452 0.0f, 1.0f, 0.1f,
7454 static const float quad4[] =
7456 0.0f, 0.0f, 0.1f,
7457 0.0f, 1.0f, 0.1f,
7458 1.0f, 0.0f, 0.1f,
7459 1.0f, 1.0f, 0.1f,
7461 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7462 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7464 window = create_window();
7465 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7466 ok(!!d3d, "Failed to create a D3D object.\n");
7467 if (!(device = create_device(d3d, window, window, TRUE)))
7469 skip("Failed to create a D3D device, skipping tests.\n");
7470 goto done;
7473 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7474 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7475 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7477 skip("No vs_1_1 support, skipping tests.\n");
7478 IDirect3DDevice9_Release(device);
7479 goto done;
7482 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7483 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7485 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7486 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7487 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7489 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7490 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7491 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7493 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7494 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7495 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7496 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7497 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7498 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7500 hr = IDirect3DDevice9_BeginScene(device);
7501 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7503 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7504 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7506 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7508 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7509 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7513 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7514 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7516 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7518 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7519 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7521 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7522 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7524 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7526 hr = IDirect3DDevice9_EndScene(device);
7527 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7529 color = getPixelColor(device, 160, 360);
7530 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7531 color = getPixelColor(device, 480, 360);
7532 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7533 color = getPixelColor(device, 160, 120);
7534 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7535 color = getPixelColor(device, 480, 160);
7536 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7538 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7539 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7541 IDirect3DVertexShader9_Release(shader_sge_vec);
7542 IDirect3DVertexShader9_Release(shader_slt_vec);
7543 IDirect3DVertexShader9_Release(shader_sge_scalar);
7544 IDirect3DVertexShader9_Release(shader_slt_scalar);
7545 refcount = IDirect3DDevice9_Release(device);
7546 ok(!refcount, "Device has %u references left.\n", refcount);
7547 done:
7548 IDirect3D9_Release(d3d);
7549 DestroyWindow(window);
7552 static void test_vshader_input(void)
7554 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7555 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7556 IDirect3DVertexDeclaration9 *decl_nocolor;
7557 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7558 D3DADAPTER_IDENTIFIER9 identifier;
7559 IDirect3DPixelShader9 *ps;
7560 IDirect3DDevice9 *device;
7561 IDirect3D9 *d3d;
7562 ULONG refcount;
7563 unsigned int i;
7564 D3DCAPS9 caps;
7565 DWORD color;
7566 HWND window;
7567 HRESULT hr;
7568 BOOL warp;
7570 static const DWORD swapped_shader_code_3[] =
7572 0xfffe0300, /* vs_3_0 */
7573 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7574 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7575 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7576 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7577 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7578 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7579 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7580 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7581 0x0000ffff /* end */
7583 static const DWORD swapped_shader_code_1[] =
7585 0xfffe0101, /* vs_1_1 */
7586 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7587 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7588 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7589 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7590 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7591 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7592 0x0000ffff /* end */
7594 static const DWORD swapped_shader_code_2[] =
7596 0xfffe0200, /* vs_2_0 */
7597 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7598 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7599 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7600 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7601 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7602 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7603 0x0000ffff /* end */
7605 static const DWORD texcoord_color_shader_code_3[] =
7607 0xfffe0300, /* vs_3_0 */
7608 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7609 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7610 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7611 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7612 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7613 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7614 0x0000ffff /* end */
7616 static const DWORD texcoord_color_shader_code_2[] =
7618 0xfffe0200, /* vs_2_0 */
7619 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7620 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7621 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7622 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7623 0x0000ffff /* end */
7625 static const DWORD texcoord_color_shader_code_1[] =
7627 0xfffe0101, /* vs_1_1 */
7628 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7629 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7630 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7631 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7632 0x0000ffff /* end */
7634 static const DWORD color_color_shader_code_3[] =
7636 0xfffe0300, /* vs_3_0 */
7637 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7638 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7639 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7640 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7641 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7642 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7643 0x0000ffff /* end */
7645 static const DWORD color_color_shader_code_2[] =
7647 0xfffe0200, /* vs_2_0 */
7648 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7649 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7650 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7651 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7652 0x0000ffff /* end */
7654 static const DWORD color_color_shader_code_1[] =
7656 0xfffe0101, /* vs_1_1 */
7657 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7658 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7659 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7660 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7661 0x0000ffff /* end */
7663 static const DWORD ps3_code[] =
7665 0xffff0300, /* ps_3_0 */
7666 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7667 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7668 0x0000ffff /* end */
7670 static const float quad1[] =
7672 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7673 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7674 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7675 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7677 static const float quad2[] =
7679 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7680 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7681 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7682 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7684 static const float quad3[] =
7686 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7687 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7688 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7689 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7691 static const float quad4[] =
7693 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7694 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7695 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7696 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7698 static const float quad1_modified[] =
7700 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7701 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7702 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7703 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7705 static const float quad2_modified[] =
7707 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7708 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7709 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7710 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7712 static const struct
7714 struct vec3 position;
7715 DWORD diffuse;
7717 quad1_color[] =
7719 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7720 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7721 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7722 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7724 quad2_color[] =
7726 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7727 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7728 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7729 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7731 quad3_color[] =
7733 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7734 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7735 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7736 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7738 static const float quad4_color[] =
7740 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7741 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7742 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7743 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7745 static const struct vec3 quad_nocolor[] =
7747 {-1.0f, -1.0f, 0.1f},
7748 {-1.0f, 1.0f, 0.1f},
7749 { 1.0f, -1.0f, 0.1f},
7750 { 1.0f, 1.0f, 0.1f},
7752 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7754 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7755 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7756 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7757 D3DDECL_END()
7759 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7761 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7762 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7763 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7764 D3DDECL_END()
7766 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7768 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7769 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7770 D3DDECL_END()
7772 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7774 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7775 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7776 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7777 D3DDECL_END()
7779 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7781 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7782 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7783 D3DDECL_END()
7785 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7787 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7788 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7789 D3DDECL_END()
7791 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7793 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7794 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7795 D3DDECL_END()
7797 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7799 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7800 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7801 D3DDECL_END()
7803 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7805 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7806 D3DDECL_END()
7808 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7809 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7811 window = create_window();
7812 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7813 ok(!!d3d, "Failed to create a D3D object.\n");
7814 if (!(device = create_device(d3d, window, window, TRUE)))
7816 skip("Failed to create a D3D device, skipping tests.\n");
7817 goto done;
7820 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7821 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7822 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7824 skip("No vs_3_0 support, skipping tests.\n");
7825 IDirect3DDevice9_Release(device);
7826 goto done;
7829 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7830 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7831 warp = adapter_is_warp(&identifier);
7833 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7834 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7835 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7836 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7837 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7838 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7839 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7840 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7842 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7843 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7844 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7845 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7846 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7847 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7848 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7849 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7850 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7851 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7853 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7854 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7856 for (i = 1; i <= 3; ++i)
7858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7859 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7860 if(i == 3) {
7861 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7862 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7863 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7865 } else if(i == 2){
7866 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7867 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7868 } else if(i == 1) {
7869 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7870 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7873 hr = IDirect3DDevice9_BeginScene(device);
7874 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7876 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7877 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7879 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7880 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7882 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7884 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7885 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7887 if (i == 3 || i == 2)
7888 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7889 else if (i == 1)
7890 /* Succeeds or fails, depending on SW or HW vertex processing. */
7891 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7893 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7894 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7896 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7898 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7899 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7900 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7901 if (i == 3 || i == 2)
7902 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7903 else if (i == 1)
7904 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7906 hr = IDirect3DDevice9_EndScene(device);
7907 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7909 if(i == 3 || i == 2) {
7910 color = getPixelColor(device, 160, 360);
7911 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7912 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7914 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7915 color = getPixelColor(device, 480, 360);
7916 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7917 * mostly random data as input. */
7918 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7919 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7920 color = getPixelColor(device, 160, 120);
7921 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7922 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7923 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7925 color = getPixelColor(device, 480, 160);
7926 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7927 } else if(i == 1) {
7928 color = getPixelColor(device, 160, 360);
7929 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7930 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7931 color = getPixelColor(device, 480, 360);
7932 /* Accept the clear color as well in this case, since SW VP
7933 * returns an error. On the Windows 8 testbot (WARP) the draw
7934 * succeeds, but uses mostly random data as input. */
7935 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7936 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7937 color = getPixelColor(device, 160, 120);
7938 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7939 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7940 color = getPixelColor(device, 480, 160);
7941 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7944 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7945 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7947 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7948 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7950 /* Now find out if the whole streams are re-read, or just the last
7951 * active value for the vertices is used. */
7952 hr = IDirect3DDevice9_BeginScene(device);
7953 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7955 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7956 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7958 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7959 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7961 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7963 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7964 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7965 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7966 if (i == 3 || i == 2)
7967 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7968 else if (i == 1)
7969 /* Succeeds or fails, depending on SW or HW vertex processing. */
7970 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7972 hr = IDirect3DDevice9_EndScene(device);
7973 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7975 color = getPixelColor(device, 480, 350);
7976 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7977 * as well.
7979 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7980 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7981 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7982 * refrast's result.
7984 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7986 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7987 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7988 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7991 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7993 IDirect3DDevice9_SetVertexShader(device, NULL);
7994 IDirect3DDevice9_SetPixelShader(device, NULL);
7995 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7997 IDirect3DVertexShader9_Release(swapped_shader);
8000 for (i = 1; i <= 3; ++i)
8002 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8003 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8004 if(i == 3) {
8005 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8006 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8007 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8008 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8009 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8010 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8011 } else if(i == 2){
8012 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8013 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8014 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8015 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8016 } else if(i == 1) {
8017 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8018 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8019 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8020 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8023 hr = IDirect3DDevice9_BeginScene(device);
8024 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8026 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8027 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8028 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8029 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8031 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8033 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8034 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8036 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8037 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8038 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8039 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8040 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8041 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8043 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8044 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8045 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8046 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8048 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8050 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8051 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8052 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8053 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8055 hr = IDirect3DDevice9_EndScene(device);
8056 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8058 color = getPixelColor(device, 160, 360);
8059 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8060 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8061 color = getPixelColor(device, 480, 360);
8062 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8063 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8064 color = getPixelColor(device, 160, 120);
8065 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8066 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8067 color = getPixelColor(device, 480, 160);
8068 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8069 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8072 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8074 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8075 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8078 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8080 hr = IDirect3DDevice9_BeginScene(device);
8081 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8083 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8084 hr = IDirect3DDevice9_EndScene(device);
8085 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8087 /* WARP ends up using the color attribute from the previous draw. Let's mark
8088 * that behavior as broken. */
8089 color = getPixelColor(device, 160, 360);
8090 ok(color_match(color, 0x00000000, 1)
8091 || broken(color_match(color, 0x00ffff00, 1)),
8092 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8094 IDirect3DDevice9_SetVertexShader(device, NULL);
8095 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8096 IDirect3DDevice9_SetPixelShader(device, NULL);
8098 IDirect3DVertexShader9_Release(texcoord_color_shader);
8099 IDirect3DVertexShader9_Release(color_color_shader);
8102 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8103 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8104 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8105 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8107 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8108 IDirect3DVertexDeclaration9_Release(decl_color_color);
8109 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8110 IDirect3DVertexDeclaration9_Release(decl_color_float);
8111 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8113 IDirect3DPixelShader9_Release(ps);
8114 refcount = IDirect3DDevice9_Release(device);
8115 ok(!refcount, "Device has %u references left.\n", refcount);
8116 done:
8117 IDirect3D9_Release(d3d);
8118 DestroyWindow(window);
8121 static void srgbtexture_test(void)
8123 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8124 * texture stage state to render a quad using that texture. The resulting
8125 * color components should be 0x36 (~ 0.21), per this formula:
8126 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8127 * This is true where srgb_color > 0.04045. */
8128 struct IDirect3DTexture9 *texture;
8129 struct IDirect3DSurface9 *surface;
8130 IDirect3DDevice9 *device;
8131 IDirect3D9 *d3d;
8132 D3DCOLOR color;
8133 ULONG refcount;
8134 HWND window;
8135 HRESULT hr;
8137 static const float quad[] =
8139 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8140 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8141 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8142 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8145 window = create_window();
8146 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8147 ok(!!d3d, "Failed to create a D3D object.\n");
8148 if (!(device = create_device(d3d, window, window, TRUE)))
8150 skip("Failed to create a D3D device, skipping tests.\n");
8151 goto done;
8154 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8155 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8157 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8158 IDirect3DDevice9_Release(device);
8159 goto done;
8162 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8163 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8164 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8165 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8167 fill_surface(surface, 0xff7f7f7f, 0);
8168 IDirect3DSurface9_Release(surface);
8170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8171 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8172 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8173 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8175 hr = IDirect3DDevice9_BeginScene(device);
8176 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8178 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8179 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8180 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8181 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8182 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8183 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8185 hr = IDirect3DDevice9_EndScene(device);
8186 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8188 color = getPixelColor(device, 320, 240);
8189 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8191 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8192 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8194 IDirect3DTexture9_Release(texture);
8195 refcount = IDirect3DDevice9_Release(device);
8196 ok(!refcount, "Device has %u references left.\n", refcount);
8197 done:
8198 IDirect3D9_Release(d3d);
8199 DestroyWindow(window);
8202 static void test_shademode(void)
8204 IDirect3DVertexBuffer9 *vb_strip;
8205 IDirect3DVertexBuffer9 *vb_list;
8206 IDirect3DVertexShader9 *vs;
8207 IDirect3DPixelShader9 *ps;
8208 IDirect3DDevice9 *device;
8209 DWORD color0, color1;
8210 void *data = NULL;
8211 IDirect3D9 *d3d;
8212 ULONG refcount;
8213 D3DCAPS9 caps;
8214 HWND window;
8215 HRESULT hr;
8216 UINT i;
8217 static const DWORD vs1_code[] =
8219 0xfffe0101, /* vs_1_1 */
8220 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8221 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8222 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8223 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8224 0x0000ffff
8226 static const DWORD vs2_code[] =
8228 0xfffe0200, /* vs_2_0 */
8229 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8230 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8231 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8232 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8233 0x0000ffff
8235 static const DWORD vs3_code[] =
8237 0xfffe0300, /* vs_3_0 */
8238 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8239 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8240 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8241 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8242 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8243 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8244 0x0000ffff
8246 static const DWORD ps1_code[] =
8248 0xffff0101, /* ps_1_1 */
8249 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8250 0x0000ffff
8252 static const DWORD ps2_code[] =
8254 0xffff0200, /* ps_2_0 */
8255 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8256 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8257 0x0000ffff
8259 static const DWORD ps3_code[] =
8261 0xffff0300, /* ps_3_0 */
8262 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8263 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8264 0x0000ffff
8266 static const struct
8268 struct vec3 position;
8269 DWORD diffuse;
8271 quad_strip[] =
8273 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8274 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8275 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8276 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8278 quad_list[] =
8280 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8281 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8282 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8284 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8285 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8286 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8288 static const struct test_shader
8290 DWORD version;
8291 const DWORD *code;
8293 novs = {0, NULL},
8294 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8295 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8296 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8297 nops = {0, NULL},
8298 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8299 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8300 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8301 static const struct
8303 const struct test_shader *vs, *ps;
8304 DWORD primtype;
8305 DWORD shademode;
8306 DWORD color0, color1;
8307 BOOL todo;
8309 tests[] =
8311 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8312 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8313 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8314 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8315 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8316 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8317 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8318 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8319 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8320 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8321 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8322 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8323 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8324 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8325 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8326 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8329 window = create_window();
8330 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8331 ok(!!d3d, "Failed to create a D3D object.\n");
8332 if (!(device = create_device(d3d, window, window, TRUE)))
8334 skip("Failed to create a D3D device, skipping tests.\n");
8335 goto done;
8338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8341 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8343 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8344 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8346 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8347 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8348 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8349 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8350 memcpy(data, quad_strip, sizeof(quad_strip));
8351 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8352 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8354 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8355 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8356 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8357 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8358 memcpy(data, quad_list, sizeof(quad_list));
8359 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8360 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8362 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8363 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8365 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8366 * the color fixups we have to do for FLAT shading will be dependent on that. */
8368 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8370 if (tests[i].vs->version)
8372 if (caps.VertexShaderVersion >= tests[i].vs->version)
8374 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8375 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8376 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8377 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8379 else
8381 skip("Shader version unsupported, skipping some tests.\n");
8382 continue;
8385 else
8387 vs = NULL;
8389 if (tests[i].ps->version)
8391 if (caps.PixelShaderVersion >= tests[i].ps->version)
8393 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8394 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8395 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8396 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8398 else
8400 skip("Shader version unsupported, skipping some tests.\n");
8401 if (vs)
8403 IDirect3DDevice9_SetVertexShader(device, NULL);
8404 IDirect3DVertexShader9_Release(vs);
8406 continue;
8409 else
8411 ps = NULL;
8414 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8415 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8416 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8419 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8422 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8424 hr = IDirect3DDevice9_BeginScene(device);
8425 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8426 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8427 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8428 hr = IDirect3DDevice9_EndScene(device);
8429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8431 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8432 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8434 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8435 * each triangle. This requires EXT_provoking_vertex or similar
8436 * functionality being available. */
8437 /* PHONG should be the same as GOURAUD, since no hardware implements
8438 * this. */
8439 todo_wine_if (tests[i].todo)
8441 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8442 i, color0, tests[i].color0);
8443 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8444 i, color1, tests[i].color1);
8446 IDirect3DDevice9_SetVertexShader(device, NULL);
8447 IDirect3DDevice9_SetPixelShader(device, NULL);
8449 if (ps)
8450 IDirect3DPixelShader9_Release(ps);
8451 if (vs)
8452 IDirect3DVertexShader9_Release(vs);
8455 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8456 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8458 IDirect3DVertexBuffer9_Release(vb_strip);
8459 IDirect3DVertexBuffer9_Release(vb_list);
8460 refcount = IDirect3DDevice9_Release(device);
8461 ok(!refcount, "Device has %u references left.\n", refcount);
8462 done:
8463 IDirect3D9_Release(d3d);
8464 DestroyWindow(window);
8467 static void test_blend(void)
8469 IDirect3DSurface9 *backbuffer, *offscreen;
8470 IDirect3DTexture9 *offscreenTexture;
8471 IDirect3DDevice9 *device;
8472 IDirect3D9 *d3d;
8473 D3DCOLOR color;
8474 ULONG refcount;
8475 HWND window;
8476 HRESULT hr;
8478 static const struct
8480 struct vec3 position;
8481 DWORD diffuse;
8483 quad1[] =
8485 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8486 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8487 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8488 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8490 quad2[] =
8492 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8493 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8494 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8495 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8497 static const float composite_quad[][5] =
8499 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8500 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8501 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8502 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8505 window = create_window();
8506 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8507 ok(!!d3d, "Failed to create a D3D object.\n");
8508 if (!(device = create_device(d3d, window, window, TRUE)))
8510 skip("Failed to create a D3D device, skipping tests.\n");
8511 goto done;
8514 /* Clear the render target with alpha = 0.5 */
8515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8516 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8518 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8519 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8520 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8522 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8523 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8525 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8526 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8528 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8529 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8531 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8532 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8533 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8534 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8535 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8536 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8537 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8538 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8539 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8540 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8543 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8544 hr = IDirect3DDevice9_BeginScene(device);
8545 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8547 /* Draw two quads, one with src alpha blending, one with dest alpha
8548 * blending. */
8549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8550 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8552 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8553 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8554 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8557 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8559 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8561 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8563 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8564 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8565 * "don't work" on render targets without alpha channel, they give
8566 * essentially ZERO and ONE blend factors. */
8567 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8568 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8569 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8570 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8573 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8575 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8577 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8580 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8581 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8582 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8583 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8584 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8586 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8587 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8589 /* Render the offscreen texture onto the frame buffer to be able to
8590 * compare it regularly. Disable alpha blending for the final
8591 * composition. */
8592 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8593 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8594 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8595 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8597 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8598 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8600 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8602 hr = IDirect3DDevice9_EndScene(device);
8603 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8605 color = getPixelColor(device, 160, 360);
8606 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8607 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8609 color = getPixelColor(device, 160, 120);
8610 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8611 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8613 color = getPixelColor(device, 480, 360);
8614 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8615 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8617 color = getPixelColor(device, 480, 120);
8618 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8619 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8621 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8623 IDirect3DSurface9_Release(backbuffer);
8624 IDirect3DTexture9_Release(offscreenTexture);
8625 IDirect3DSurface9_Release(offscreen);
8626 refcount = IDirect3DDevice9_Release(device);
8627 ok(!refcount, "Device has %u references left.\n", refcount);
8628 done:
8629 IDirect3D9_Release(d3d);
8630 DestroyWindow(window);
8633 static void fixed_function_decl_test(void)
8635 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8636 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8637 IDirect3DVertexBuffer9 *vb, *vb2;
8638 IDirect3DDevice9 *device;
8639 BOOL s_ok, ub_ok, f_ok;
8640 DWORD color, size, i;
8641 IDirect3D9 *d3d;
8642 ULONG refcount;
8643 D3DCAPS9 caps;
8644 HWND window;
8645 void *data;
8646 HRESULT hr;
8648 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8649 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8650 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8651 D3DDECL_END()
8653 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8654 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8655 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8656 D3DDECL_END()
8658 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8659 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8660 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8661 D3DDECL_END()
8663 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8664 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8665 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8666 D3DDECL_END()
8668 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8669 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8670 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8671 D3DDECL_END()
8673 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8674 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8675 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8676 D3DDECL_END()
8678 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8679 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8680 D3DDECL_END()
8682 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8683 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8684 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8685 D3DDECL_END()
8687 static const struct
8689 struct vec3 position;
8690 DWORD diffuse;
8692 quad1[] = /* D3DCOLOR */
8694 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8695 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8696 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8697 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8699 quad2[] = /* UBYTE4N */
8701 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8702 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8703 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8704 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8706 static const struct
8708 struct vec3 position;
8709 struct { unsigned short x, y, z, w; } color;
8711 quad3[] = /* USHORT4N */
8713 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8714 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8715 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8716 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8718 static const struct
8720 struct vec3 position;
8721 struct vec4 color;
8723 quad4[] =
8725 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8726 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8727 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8728 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8730 static const DWORD colors[] =
8732 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8733 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8734 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8735 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8736 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8737 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8738 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8739 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8740 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8741 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8742 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8743 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8744 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8745 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8746 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8747 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8749 static const float quads[] =
8751 -1.0f, -1.0f, 0.1f,
8752 -1.0f, 0.0f, 0.1f,
8753 0.0f, -1.0f, 0.1f,
8754 0.0f, 0.0f, 0.1f,
8756 0.0f, -1.0f, 0.1f,
8757 0.0f, 0.0f, 0.1f,
8758 1.0f, -1.0f, 0.1f,
8759 1.0f, 0.0f, 0.1f,
8761 0.0f, 0.0f, 0.1f,
8762 0.0f, 1.0f, 0.1f,
8763 1.0f, 0.0f, 0.1f,
8764 1.0f, 1.0f, 0.1f,
8766 -1.0f, 0.0f, 0.1f,
8767 -1.0f, 1.0f, 0.1f,
8768 0.0f, 0.0f, 0.1f,
8769 0.0f, 1.0f, 0.1f,
8771 static const struct
8773 struct vec4 position;
8774 DWORD diffuse;
8776 quad_transformed[] =
8778 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8779 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8780 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8781 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8784 window = create_window();
8785 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8786 ok(!!d3d, "Failed to create a D3D object.\n");
8787 if (!(device = create_device(d3d, window, window, TRUE)))
8789 skip("Failed to create a D3D device, skipping tests.\n");
8790 goto done;
8793 memset(&caps, 0, sizeof(caps));
8794 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8795 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8797 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8798 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8800 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8801 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8802 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8803 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8804 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8805 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8806 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8807 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8808 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8809 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8810 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8811 } else {
8812 trace("D3DDTCAPS_UBYTE4N not supported\n");
8813 dcl_ubyte_2 = NULL;
8814 dcl_ubyte = NULL;
8816 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8817 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8818 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8819 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8820 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8821 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8823 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8824 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8825 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8826 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8829 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8831 hr = IDirect3DDevice9_BeginScene(device);
8832 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8834 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8835 if (dcl_color)
8837 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8838 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8840 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8843 /* Tests with non-standard fixed function types fail on the refrast. The
8844 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8845 * All those differences even though we're using software vertex
8846 * processing. Doh! */
8847 if (dcl_ubyte)
8849 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8850 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8852 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8853 ub_ok = SUCCEEDED(hr);
8856 if (dcl_short)
8858 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8859 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8861 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8862 s_ok = SUCCEEDED(hr);
8865 if (dcl_float)
8867 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8868 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8870 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8871 f_ok = SUCCEEDED(hr);
8874 hr = IDirect3DDevice9_EndScene(device);
8875 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8877 if(dcl_short) {
8878 color = getPixelColor(device, 480, 360);
8879 ok(color == 0x000000ff || !s_ok,
8880 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8882 if(dcl_ubyte) {
8883 color = getPixelColor(device, 160, 120);
8884 ok(color == 0x0000ffff || !ub_ok,
8885 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8887 if(dcl_color) {
8888 color = getPixelColor(device, 160, 360);
8889 ok(color == 0x00ffff00,
8890 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8892 if(dcl_float) {
8893 color = getPixelColor(device, 480, 120);
8894 ok(color == 0x00ff0000 || !f_ok,
8895 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8897 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8899 /* The following test with vertex buffers doesn't serve to find out new
8900 * information from windows. It is a plain regression test because wined3d
8901 * uses different codepaths for attribute conversion with vertex buffers.
8902 * It makes sure that the vertex buffer one works, while the above tests
8903 * whether the immediate mode code works. */
8904 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8905 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8906 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8907 hr = IDirect3DDevice9_BeginScene(device);
8908 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8910 if (dcl_color)
8912 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8913 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8914 memcpy(data, quad1, sizeof(quad1));
8915 hr = IDirect3DVertexBuffer9_Unlock(vb);
8916 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8917 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8918 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8919 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8920 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8921 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8922 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8925 if (dcl_ubyte)
8927 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8928 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8929 memcpy(data, quad2, sizeof(quad2));
8930 hr = IDirect3DVertexBuffer9_Unlock(vb);
8931 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8932 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8933 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8934 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8935 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8936 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8937 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8938 ub_ok = SUCCEEDED(hr);
8941 if (dcl_short)
8943 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8944 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8945 memcpy(data, quad3, sizeof(quad3));
8946 hr = IDirect3DVertexBuffer9_Unlock(vb);
8947 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8948 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8949 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8950 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8951 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8952 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8953 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8954 s_ok = SUCCEEDED(hr);
8957 if (dcl_float)
8959 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8960 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8961 memcpy(data, quad4, sizeof(quad4));
8962 hr = IDirect3DVertexBuffer9_Unlock(vb);
8963 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8964 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8965 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8966 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[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 f_ok = SUCCEEDED(hr);
8973 hr = IDirect3DDevice9_EndScene(device);
8974 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8976 if(dcl_short) {
8977 color = getPixelColor(device, 480, 360);
8978 ok(color == 0x000000ff || !s_ok,
8979 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8981 if(dcl_ubyte) {
8982 color = getPixelColor(device, 160, 120);
8983 ok(color == 0x0000ffff || !ub_ok,
8984 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8986 if(dcl_color) {
8987 color = getPixelColor(device, 160, 360);
8988 ok(color == 0x00ffff00,
8989 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8991 if(dcl_float) {
8992 color = getPixelColor(device, 480, 120);
8993 ok(color == 0x00ff0000 || !f_ok,
8994 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8996 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8998 /* Test with no diffuse color attribute. */
8999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9000 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9002 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9003 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9004 hr = IDirect3DDevice9_BeginScene(device);
9005 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9008 hr = IDirect3DDevice9_EndScene(device);
9009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9011 color = getPixelColor(device, 160, 360);
9012 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9014 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9016 /* Test what happens with specular lighting enabled and no specular color attribute. */
9017 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9019 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9021 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9022 hr = IDirect3DDevice9_BeginScene(device);
9023 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9025 if (dcl_color)
9027 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9028 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9030 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9032 if (dcl_ubyte)
9034 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9035 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9036 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9037 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9038 ub_ok = SUCCEEDED(hr);
9040 if (dcl_short)
9042 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9043 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9045 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9046 s_ok = SUCCEEDED(hr);
9048 if (dcl_float)
9050 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9051 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9052 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9053 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9054 f_ok = SUCCEEDED(hr);
9057 hr = IDirect3DDevice9_EndScene(device);
9058 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9060 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9062 if (dcl_short)
9064 color = getPixelColor(device, 480, 360);
9065 ok(color == 0x000000ff || !s_ok,
9066 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9068 if (dcl_ubyte)
9070 color = getPixelColor(device, 160, 120);
9071 ok(color == 0x0000ffff || !ub_ok,
9072 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9074 if (dcl_color)
9076 color = getPixelColor(device, 160, 360);
9077 ok(color == 0x00ffff00,
9078 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9080 if (dcl_float)
9082 color = getPixelColor(device, 480, 120);
9083 ok(color == 0x00ff0000 || !f_ok,
9084 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9086 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9088 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9089 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9090 memcpy(data, quad_transformed, sizeof(quad_transformed));
9091 hr = IDirect3DVertexBuffer9_Unlock(vb);
9092 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9094 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9095 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9098 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9100 hr = IDirect3DDevice9_BeginScene(device);
9101 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9102 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9103 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9104 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9105 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9106 hr = IDirect3DDevice9_EndScene(device);
9107 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9109 color = getPixelColor(device, 88, 108);
9110 ok(color == 0x000000ff,
9111 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9112 color = getPixelColor(device, 92, 108);
9113 ok(color == 0x000000ff,
9114 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9115 color = getPixelColor(device, 88, 112);
9116 ok(color == 0x000000ff,
9117 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9118 color = getPixelColor(device, 92, 112);
9119 ok(color == 0x00ffff00,
9120 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9122 color = getPixelColor(device, 568, 108);
9123 ok(color == 0x000000ff,
9124 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9125 color = getPixelColor(device, 572, 108);
9126 ok(color == 0x000000ff,
9127 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9128 color = getPixelColor(device, 568, 112);
9129 ok(color == 0x00ffff00,
9130 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9131 color = getPixelColor(device, 572, 112);
9132 ok(color == 0x000000ff,
9133 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9135 color = getPixelColor(device, 88, 298);
9136 ok(color == 0x000000ff,
9137 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9138 color = getPixelColor(device, 92, 298);
9139 ok(color == 0x00ffff00,
9140 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9141 color = getPixelColor(device, 88, 302);
9142 ok(color == 0x000000ff,
9143 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9144 color = getPixelColor(device, 92, 302);
9145 ok(color == 0x000000ff,
9146 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9148 color = getPixelColor(device, 568, 298);
9149 ok(color == 0x00ffff00,
9150 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9151 color = getPixelColor(device, 572, 298);
9152 ok(color == 0x000000ff,
9153 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9154 color = getPixelColor(device, 568, 302);
9155 ok(color == 0x000000ff,
9156 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9157 color = getPixelColor(device, 572, 302);
9158 ok(color == 0x000000ff,
9159 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9161 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9163 /* This test is pointless without those two declarations: */
9164 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9165 skip("color-ubyte switching test declarations aren't supported\n");
9166 goto out;
9169 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9170 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9171 memcpy(data, quads, sizeof(quads));
9172 hr = IDirect3DVertexBuffer9_Unlock(vb);
9173 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9174 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9175 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9176 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9177 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9178 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9179 memcpy(data, colors, sizeof(colors));
9180 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9181 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9183 for(i = 0; i < 2; i++) {
9184 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9185 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9187 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9188 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9189 if(i == 0) {
9190 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9191 } else {
9192 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9194 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9196 hr = IDirect3DDevice9_BeginScene(device);
9197 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9199 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9200 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9201 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9202 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9203 ub_ok = SUCCEEDED(hr);
9205 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9206 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9207 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9208 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9210 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9211 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9212 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9213 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9214 ub_ok = (SUCCEEDED(hr) && ub_ok);
9216 hr = IDirect3DDevice9_EndScene(device);
9217 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9219 if(i == 0) {
9220 color = getPixelColor(device, 480, 360);
9221 ok(color == 0x00ff0000,
9222 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9223 color = getPixelColor(device, 160, 120);
9224 ok(color == 0x00ffffff,
9225 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9226 color = getPixelColor(device, 160, 360);
9227 ok(color == 0x000000ff || !ub_ok,
9228 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9229 color = getPixelColor(device, 480, 120);
9230 ok(color == 0x000000ff || !ub_ok,
9231 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9232 } else {
9233 color = getPixelColor(device, 480, 360);
9234 ok(color == 0x000000ff,
9235 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9236 color = getPixelColor(device, 160, 120);
9237 ok(color == 0x00ffffff,
9238 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9239 color = getPixelColor(device, 160, 360);
9240 ok(color == 0x00ff0000 || !ub_ok,
9241 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9242 color = getPixelColor(device, 480, 120);
9243 ok(color == 0x00ff0000 || !ub_ok,
9244 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9246 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9249 IDirect3DVertexBuffer9_Release(vb2);
9250 out:
9251 IDirect3DVertexBuffer9_Release(vb);
9252 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9253 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9254 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9255 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9256 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9257 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9258 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9259 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9260 refcount = IDirect3DDevice9_Release(device);
9261 ok(!refcount, "Device has %u references left.\n", refcount);
9262 done:
9263 IDirect3D9_Release(d3d);
9264 DestroyWindow(window);
9267 static void test_vshader_float16(void)
9269 IDirect3DVertexDeclaration9 *vdecl = NULL;
9270 IDirect3DVertexBuffer9 *buffer = NULL;
9271 IDirect3DVertexShader9 *shader;
9272 IDirect3DDevice9 *device;
9273 IDirect3D9 *d3d;
9274 ULONG refcount;
9275 D3DCAPS9 caps;
9276 DWORD color;
9277 HWND window;
9278 void *data;
9279 HRESULT hr;
9281 static const D3DVERTEXELEMENT9 decl_elements[] =
9283 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9284 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9285 D3DDECL_END()
9287 static const DWORD shader_code[] =
9289 0xfffe0101, /* vs_1_1 */
9290 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9291 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9292 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9293 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9294 0x0000ffff,
9296 static const struct vertex_float16color
9298 float x, y, z;
9299 DWORD c1, c2;
9301 quad[] =
9303 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9304 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9305 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9306 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9308 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9309 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9310 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9311 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9313 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9314 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9315 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9316 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9318 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9319 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9320 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9321 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9324 window = create_window();
9325 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9326 ok(!!d3d, "Failed to create a D3D object.\n");
9327 if (!(device = create_device(d3d, window, window, TRUE)))
9329 skip("Failed to create a D3D device, skipping tests.\n");
9330 goto done;
9333 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9334 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9335 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9337 skip("No vs_3_0 support, skipping tests.\n");
9338 IDirect3DDevice9_Release(device);
9339 goto done;
9342 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9343 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9345 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9346 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9347 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9348 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9349 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9350 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9352 hr = IDirect3DDevice9_BeginScene(device);
9353 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9354 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9355 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9356 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9357 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9359 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9361 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9363 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9364 hr = IDirect3DDevice9_EndScene(device);
9365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9367 color = getPixelColor(device, 480, 360);
9368 ok(color == 0x00ff0000,
9369 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9370 color = getPixelColor(device, 160, 120);
9371 ok(color == 0x00000000,
9372 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9373 color = getPixelColor(device, 160, 360);
9374 ok(color == 0x0000ff00,
9375 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9376 color = getPixelColor(device, 480, 120);
9377 ok(color == 0x000000ff,
9378 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9379 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9384 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9385 D3DPOOL_MANAGED, &buffer, NULL);
9386 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9387 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9388 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9389 memcpy(data, quad, sizeof(quad));
9390 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9391 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9392 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9393 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9395 hr = IDirect3DDevice9_BeginScene(device);
9396 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9397 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9398 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9399 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9400 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9401 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9402 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9403 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9404 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9405 hr = IDirect3DDevice9_EndScene(device);
9406 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9408 color = getPixelColor(device, 480, 360);
9409 ok(color == 0x00ff0000,
9410 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9411 color = getPixelColor(device, 160, 120);
9412 ok(color == 0x00000000,
9413 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9414 color = getPixelColor(device, 160, 360);
9415 ok(color == 0x0000ff00,
9416 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9417 color = getPixelColor(device, 480, 120);
9418 ok(color == 0x000000ff,
9419 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9420 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9422 IDirect3DVertexDeclaration9_Release(vdecl);
9423 IDirect3DVertexShader9_Release(shader);
9424 IDirect3DVertexBuffer9_Release(buffer);
9425 refcount = IDirect3DDevice9_Release(device);
9426 ok(!refcount, "Device has %u references left.\n", refcount);
9427 done:
9428 IDirect3D9_Release(d3d);
9429 DestroyWindow(window);
9432 static void conditional_np2_repeat_test(void)
9434 IDirect3DTexture9 *texture;
9435 IDirect3DDevice9 *device;
9436 D3DLOCKED_RECT rect;
9437 unsigned int x, y;
9438 DWORD *dst, color;
9439 IDirect3D9 *d3d;
9440 ULONG refcount;
9441 D3DCAPS9 caps;
9442 HWND window;
9443 HRESULT hr;
9445 static const float quad[] =
9447 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9448 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9449 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9450 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9453 window = create_window();
9454 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9455 ok(!!d3d, "Failed to create a D3D object.\n");
9456 if (!(device = create_device(d3d, window, window, TRUE)))
9458 skip("Failed to create a D3D device, skipping tests.\n");
9459 goto done;
9462 memset(&caps, 0, sizeof(caps));
9463 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9465 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9467 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9468 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9469 "Card has conditional NP2 support without power of two restriction set\n");
9471 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9473 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9474 IDirect3DDevice9_Release(device);
9475 goto done;
9477 else
9479 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9480 IDirect3DDevice9_Release(device);
9481 goto done;
9484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9485 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9487 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9488 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9490 memset(&rect, 0, sizeof(rect));
9491 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9492 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9493 for(y = 0; y < 10; y++) {
9494 for(x = 0; x < 10; x++) {
9495 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9496 if(x == 0 || x == 9 || y == 0 || y == 9) {
9497 *dst = 0x00ff0000;
9498 } else {
9499 *dst = 0x000000ff;
9503 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9504 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9506 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9507 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9509 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9510 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9511 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9512 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9513 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9514 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9515 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9517 hr = IDirect3DDevice9_BeginScene(device);
9518 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9520 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9521 hr = IDirect3DDevice9_EndScene(device);
9522 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9524 color = getPixelColor(device, 1, 1);
9525 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9526 color = getPixelColor(device, 639, 479);
9527 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9529 color = getPixelColor(device, 135, 101);
9530 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9531 color = getPixelColor(device, 140, 101);
9532 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9533 color = getPixelColor(device, 135, 105);
9534 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9535 color = getPixelColor(device, 140, 105);
9536 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9538 color = getPixelColor(device, 135, 376);
9539 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9540 color = getPixelColor(device, 140, 376);
9541 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9542 color = getPixelColor(device, 135, 379);
9543 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9544 color = getPixelColor(device, 140, 379);
9545 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9547 color = getPixelColor(device, 500, 101);
9548 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9549 color = getPixelColor(device, 504, 101);
9550 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9551 color = getPixelColor(device, 500, 105);
9552 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9553 color = getPixelColor(device, 504, 105);
9554 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9556 color = getPixelColor(device, 500, 376);
9557 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9558 color = getPixelColor(device, 504, 376);
9559 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9560 color = getPixelColor(device, 500, 380);
9561 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9562 color = getPixelColor(device, 504, 380);
9563 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9565 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9567 IDirect3DTexture9_Release(texture);
9568 refcount = IDirect3DDevice9_Release(device);
9569 ok(!refcount, "Device has %u references left.\n", refcount);
9570 done:
9571 IDirect3D9_Release(d3d);
9572 DestroyWindow(window);
9575 static void vface_register_test(void)
9577 IDirect3DSurface9 *surface, *backbuffer;
9578 IDirect3DVertexShader9 *vshader;
9579 IDirect3DPixelShader9 *shader;
9580 IDirect3DTexture9 *texture;
9581 IDirect3DDevice9 *device;
9582 IDirect3D9 *d3d;
9583 ULONG refcount;
9584 D3DCAPS9 caps;
9585 DWORD color;
9586 HWND window;
9587 HRESULT hr;
9589 static const DWORD shader_code[] =
9591 0xffff0300, /* ps_3_0 */
9592 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9593 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9594 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9595 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9596 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9597 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9598 0x0000ffff /* END */
9600 static const DWORD vshader_code[] =
9602 0xfffe0300, /* vs_3_0 */
9603 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9604 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9605 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9606 0x0000ffff /* end */
9608 static const float quad[] =
9610 -1.0f, -1.0f, 0.1f,
9611 1.0f, -1.0f, 0.1f,
9612 -1.0f, 0.0f, 0.1f,
9614 1.0f, -1.0f, 0.1f,
9615 1.0f, 0.0f, 0.1f,
9616 -1.0f, 0.0f, 0.1f,
9618 -1.0f, 0.0f, 0.1f,
9619 -1.0f, 1.0f, 0.1f,
9620 1.0f, 0.0f, 0.1f,
9622 1.0f, 0.0f, 0.1f,
9623 -1.0f, 1.0f, 0.1f,
9624 1.0f, 1.0f, 0.1f,
9626 static const float blit[] =
9628 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9629 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9630 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9631 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9634 window = create_window();
9635 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9636 ok(!!d3d, "Failed to create a D3D object.\n");
9637 if (!(device = create_device(d3d, window, window, TRUE)))
9639 skip("Failed to create a D3D device, skipping tests.\n");
9640 goto done;
9643 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9644 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9645 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9647 skip("No shader model 3 support, skipping tests.\n");
9648 IDirect3DDevice9_Release(device);
9649 goto done;
9652 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9653 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9654 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9655 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9656 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9657 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9658 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9659 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9661 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9662 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9663 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9664 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9665 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9666 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9667 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9668 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9674 hr = IDirect3DDevice9_BeginScene(device);
9675 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9677 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9678 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9679 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9680 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9681 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9683 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9684 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9685 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9687 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9689 /* Blit the texture onto the back buffer to make it visible */
9690 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9691 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9692 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9693 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9694 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9695 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9696 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9697 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9698 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9699 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9700 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9701 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9703 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9705 hr = IDirect3DDevice9_EndScene(device);
9706 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9708 color = getPixelColor(device, 160, 360);
9709 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9710 color = getPixelColor(device, 160, 120);
9711 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9712 color = getPixelColor(device, 480, 360);
9713 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9714 color = getPixelColor(device, 480, 120);
9715 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9716 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9717 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9719 IDirect3DPixelShader9_Release(shader);
9720 IDirect3DVertexShader9_Release(vshader);
9721 IDirect3DSurface9_Release(surface);
9722 IDirect3DSurface9_Release(backbuffer);
9723 IDirect3DTexture9_Release(texture);
9724 refcount = IDirect3DDevice9_Release(device);
9725 ok(!refcount, "Device has %u references left.\n", refcount);
9726 done:
9727 IDirect3D9_Release(d3d);
9728 DestroyWindow(window);
9731 static void fixed_function_bumpmap_test(void)
9733 IDirect3DVertexDeclaration9 *vertex_declaration;
9734 IDirect3DTexture9 *texture, *tex1, *tex2;
9735 D3DLOCKED_RECT locked_rect;
9736 IDirect3DDevice9 *device;
9737 BOOL L6V5U5_supported;
9738 float scale, offset;
9739 IDirect3D9 *d3d;
9740 unsigned int i;
9741 D3DCOLOR color;
9742 ULONG refcount;
9743 D3DCAPS9 caps;
9744 HWND window;
9745 HRESULT hr;
9747 static const float quad[][7] =
9749 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9750 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9751 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9752 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9754 static const D3DVERTEXELEMENT9 decl_elements[] =
9756 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9757 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9758 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9759 D3DDECL_END()
9761 /* use asymmetric matrix to test loading */
9762 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9764 window = create_window();
9765 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9766 ok(!!d3d, "Failed to create a D3D object.\n");
9767 if (!(device = create_device(d3d, window, window, TRUE)))
9769 skip("Failed to create a D3D device, skipping tests.\n");
9770 goto done;
9773 memset(&caps, 0, sizeof(caps));
9774 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9775 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9776 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9778 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9779 IDirect3DDevice9_Release(device);
9780 goto done;
9783 /* This check is disabled, some Windows drivers do not handle
9784 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9785 * supported, but after that bump mapping works properly. So just test if
9786 * the format is generally supported, and check the BUMPENVMAP flag. */
9787 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9788 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9789 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9790 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9792 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9793 IDirect3DDevice9_Release(device);
9794 return;
9797 /* Generate the textures */
9798 generate_bumpmap_textures(device);
9800 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9801 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9802 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9803 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9805 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9809 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9810 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9811 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9812 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9813 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9814 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9816 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9817 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9818 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9819 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9820 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9821 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9823 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9824 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9826 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9827 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9829 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9830 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9832 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9833 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9834 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9835 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9837 hr = IDirect3DDevice9_BeginScene(device);
9838 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9841 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9843 hr = IDirect3DDevice9_EndScene(device);
9844 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9846 color = getPixelColor(device, 240, 60);
9847 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9848 color = getPixelColor(device, 400, 60);
9849 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9850 color = getPixelColor(device, 80, 180);
9851 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9852 color = getPixelColor(device, 560, 180);
9853 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9854 color = getPixelColor(device, 80, 300);
9855 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9856 color = getPixelColor(device, 560, 300);
9857 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9858 color = getPixelColor(device, 240, 420);
9859 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9860 color = getPixelColor(device, 400, 420);
9861 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9862 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9863 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9865 for(i = 0; i < 2; i++) {
9866 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9867 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9868 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9869 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9870 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9871 IDirect3DTexture9_Release(texture); /* To destroy it */
9874 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9876 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9877 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9878 IDirect3DDevice9_Release(device);
9879 goto done;
9882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9883 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9884 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9885 * would only make this test more complicated
9887 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9888 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9889 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9890 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9892 memset(&locked_rect, 0, sizeof(locked_rect));
9893 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9894 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9895 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9896 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9897 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9899 memset(&locked_rect, 0, sizeof(locked_rect));
9900 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9901 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9902 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9903 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9904 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9906 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9907 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9908 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9909 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9911 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9912 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9913 scale = 2.0;
9914 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9915 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9916 offset = 0.1;
9917 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9918 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9920 hr = IDirect3DDevice9_BeginScene(device);
9921 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9923 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9924 hr = IDirect3DDevice9_EndScene(device);
9925 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9927 color = getPixelColor(device, 320, 240);
9928 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9929 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9930 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9932 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9933 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9934 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9936 /* Check a result scale factor > 1.0 */
9937 scale = 10;
9938 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9939 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9940 offset = 10;
9941 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9942 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9944 hr = IDirect3DDevice9_BeginScene(device);
9945 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9948 hr = IDirect3DDevice9_EndScene(device);
9949 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9951 color = getPixelColor(device, 320, 240);
9952 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9953 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9954 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9956 /* Check clamping in the scale factor calculation */
9957 scale = 1000;
9958 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9959 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9960 offset = -1;
9961 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9962 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9964 hr = IDirect3DDevice9_BeginScene(device);
9965 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9967 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9968 hr = IDirect3DDevice9_EndScene(device);
9969 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9971 color = getPixelColor(device, 320, 240);
9972 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9974 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9976 IDirect3DTexture9_Release(tex1);
9977 IDirect3DTexture9_Release(tex2);
9978 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9979 refcount = IDirect3DDevice9_Release(device);
9980 ok(!refcount, "Device has %u references left.\n", refcount);
9981 done:
9982 IDirect3D9_Release(d3d);
9983 DestroyWindow(window);
9986 static void stencil_cull_test(void)
9988 IDirect3DDevice9 *device;
9989 IDirect3D9 *d3d;
9990 ULONG refcount;
9991 D3DCAPS9 caps;
9992 HWND window;
9993 HRESULT hr;
9994 static const float quad1[] =
9996 -1.0, -1.0, 0.1,
9997 0.0, -1.0, 0.1,
9998 -1.0, 0.0, 0.1,
9999 0.0, 0.0, 0.1,
10001 static const float quad2[] =
10003 0.0, -1.0, 0.1,
10004 1.0, -1.0, 0.1,
10005 0.0, 0.0, 0.1,
10006 1.0, 0.0, 0.1,
10008 static const float quad3[] =
10010 0.0, 0.0, 0.1,
10011 1.0, 0.0, 0.1,
10012 0.0, 1.0, 0.1,
10013 1.0, 1.0, 0.1,
10015 static const float quad4[] =
10017 -1.0, 0.0, 0.1,
10018 0.0, 0.0, 0.1,
10019 -1.0, 1.0, 0.1,
10020 0.0, 1.0, 0.1,
10022 struct
10024 struct vec3 position;
10025 DWORD diffuse;
10027 painter[] =
10029 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10030 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10031 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10032 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10034 static const WORD indices_cw[] = {0, 1, 3};
10035 static const WORD indices_ccw[] = {0, 2, 3};
10036 unsigned int i;
10037 DWORD color;
10039 window = create_window();
10040 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10041 ok(!!d3d, "Failed to create a D3D object.\n");
10042 if (!(device = create_device(d3d, window, window, TRUE)))
10044 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10045 DestroyWindow(window);
10046 IDirect3D9_Release(d3d);
10047 return;
10049 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10050 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10051 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10053 skip("No two sided stencil support\n");
10054 goto cleanup;
10057 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10058 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10059 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10060 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10063 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10065 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10067 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10069 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10071 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10080 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10083 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10085 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10087 /* First pass: Fill the stencil buffer with some values... */
10088 hr = IDirect3DDevice9_BeginScene(device);
10089 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10092 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10093 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10094 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10095 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10096 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10097 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10098 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10101 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10103 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10104 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10105 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10106 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10107 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10108 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10109 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10112 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10113 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10114 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10115 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10116 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10117 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10118 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10121 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10122 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10123 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10125 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10126 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10127 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10129 hr = IDirect3DDevice9_EndScene(device);
10130 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10132 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10133 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10135 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10137 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10145 /* 2nd pass: Make the stencil values visible */
10146 hr = IDirect3DDevice9_BeginScene(device);
10147 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10149 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10150 for (i = 0; i < 16; ++i)
10152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10153 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10155 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10156 painter[1].diffuse = (i * 16);
10157 painter[2].diffuse = (i * 16);
10158 painter[3].diffuse = (i * 16);
10159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10160 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10162 hr = IDirect3DDevice9_EndScene(device);
10163 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10166 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10168 color = getPixelColor(device, 160, 420);
10169 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10170 color = getPixelColor(device, 160, 300);
10171 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10173 color = getPixelColor(device, 480, 420);
10174 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10175 color = getPixelColor(device, 480, 300);
10176 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10178 color = getPixelColor(device, 160, 180);
10179 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10180 color = getPixelColor(device, 160, 60);
10181 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10183 color = getPixelColor(device, 480, 180);
10184 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10185 color = getPixelColor(device, 480, 60);
10186 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10188 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10189 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10191 cleanup:
10192 refcount = IDirect3DDevice9_Release(device);
10193 ok(!refcount, "Device has %u references left.\n", refcount);
10194 IDirect3D9_Release(d3d);
10195 DestroyWindow(window);
10198 static void test_fragment_coords(void)
10200 IDirect3DSurface9 *surface = NULL, *backbuffer;
10201 IDirect3DPixelShader9 *shader, *shader_frac;
10202 IDirect3DVertexShader9 *vshader;
10203 IDirect3DDevice9 *device;
10204 D3DLOCKED_RECT lr;
10205 IDirect3D9 *d3d;
10206 ULONG refcount;
10207 D3DCAPS9 caps;
10208 DWORD color;
10209 HWND window;
10210 HRESULT hr;
10211 DWORD *pos;
10213 static const DWORD shader_code[] =
10215 0xffff0300, /* ps_3_0 */
10216 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10217 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10218 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10219 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10220 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10221 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10222 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10223 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10224 0x0000ffff /* end */
10226 static const DWORD shader_frac_code[] =
10228 0xffff0300, /* ps_3_0 */
10229 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10230 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10231 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10232 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10233 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10234 0x0000ffff /* end */
10236 static const DWORD vshader_code[] =
10238 0xfffe0300, /* vs_3_0 */
10239 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10240 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10241 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10242 0x0000ffff /* end */
10244 static const float quad[] =
10246 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10247 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10248 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10249 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10251 float constant[4] = {1.0, 0.0, 320, 240};
10253 window = create_window();
10254 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10255 ok(!!d3d, "Failed to create a D3D object.\n");
10256 if (!(device = create_device(d3d, window, window, TRUE)))
10258 skip("Failed to create a D3D device, skipping tests.\n");
10259 goto done;
10262 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10263 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10264 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10266 skip("No shader model 3 support, skipping tests.\n");
10267 IDirect3DDevice9_Release(device);
10268 goto done;
10271 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10272 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10273 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10274 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10275 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10276 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10277 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10278 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10279 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10280 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10281 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10283 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10284 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10285 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10286 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10288 hr = IDirect3DDevice9_BeginScene(device);
10289 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10290 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10291 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10293 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10294 hr = IDirect3DDevice9_EndScene(device);
10295 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10297 /* This has to be pixel exact */
10298 color = getPixelColor(device, 319, 239);
10299 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10300 color = getPixelColor(device, 320, 239);
10301 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10302 color = getPixelColor(device, 319, 240);
10303 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10304 color = getPixelColor(device, 320, 240);
10305 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10306 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10308 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10309 &surface, NULL);
10310 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10311 hr = IDirect3DDevice9_BeginScene(device);
10312 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10313 constant[2] = 16; constant[3] = 16;
10314 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10315 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10316 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10317 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10318 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10319 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10320 hr = IDirect3DDevice9_EndScene(device);
10321 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10323 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10324 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10326 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10327 color = *pos & 0x00ffffff;
10328 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10329 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10330 color = *pos & 0x00ffffff;
10331 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10332 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10333 color = *pos & 0x00ffffff;
10334 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10335 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10336 color = *pos & 0x00ffffff;
10337 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10339 hr = IDirect3DSurface9_UnlockRect(surface);
10340 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10342 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10343 * have full control over the multisampling setting inside this test
10345 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10346 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10347 hr = IDirect3DDevice9_BeginScene(device);
10348 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10349 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10350 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10352 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10353 hr = IDirect3DDevice9_EndScene(device);
10354 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10356 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10357 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10359 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10360 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10362 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10363 color = *pos & 0x00ffffff;
10364 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10366 hr = IDirect3DSurface9_UnlockRect(surface);
10367 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10369 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10370 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10371 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10372 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10373 IDirect3DPixelShader9_Release(shader);
10374 IDirect3DPixelShader9_Release(shader_frac);
10375 IDirect3DVertexShader9_Release(vshader);
10376 if(surface) IDirect3DSurface9_Release(surface);
10377 IDirect3DSurface9_Release(backbuffer);
10378 refcount = IDirect3DDevice9_Release(device);
10379 ok(!refcount, "Device has %u references left.\n", refcount);
10380 done:
10381 IDirect3D9_Release(d3d);
10382 DestroyWindow(window);
10385 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10387 D3DCOLOR color;
10389 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10390 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10391 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10392 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10393 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10395 ++r;
10396 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10397 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10398 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10399 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10400 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10402 return TRUE;
10405 static void test_pointsize(void)
10407 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10408 float ptsize, ptsizemax_orig, ptsizemin_orig;
10409 IDirect3DSurface9 *rt, *backbuffer;
10410 IDirect3DTexture9 *tex1, *tex2;
10411 IDirect3DDevice9 *device;
10412 IDirect3DVertexShader9 *vs;
10413 IDirect3DPixelShader9 *ps;
10414 D3DLOCKED_RECT lr;
10415 IDirect3D9 *d3d;
10416 D3DCOLOR color;
10417 ULONG refcount;
10418 D3DCAPS9 caps;
10419 HWND window;
10420 HRESULT hr;
10421 unsigned int i, j;
10423 static const RECT rect = {0, 0, 128, 128};
10424 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10425 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10426 static const float vertices[] =
10428 64.0f, 64.0f, 0.1f,
10429 128.0f, 64.0f, 0.1f,
10430 192.0f, 64.0f, 0.1f,
10431 256.0f, 64.0f, 0.1f,
10432 320.0f, 64.0f, 0.1f,
10433 384.0f, 64.0f, 0.1f,
10434 448.0f, 64.0f, 0.1f,
10435 512.0f, 64.0f, 0.1f,
10437 static const struct
10439 float x, y, z;
10440 float point_size;
10442 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10443 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10444 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10445 static const DWORD vshader_code[] =
10447 0xfffe0101, /* vs_1_1 */
10448 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10449 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10450 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10451 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10452 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10453 0x0000ffff
10455 static const DWORD vshader_psize_code[] =
10457 0xfffe0101, /* vs_1_1 */
10458 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10459 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10460 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10461 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10462 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10463 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10464 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10465 0x0000ffff
10467 static const DWORD pshader_code[] =
10469 0xffff0101, /* ps_1_1 */
10470 0x00000042, 0xb00f0000, /* tex t0 */
10471 0x00000042, 0xb00f0001, /* tex t1 */
10472 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10473 0x0000ffff
10475 static const DWORD pshader2_code[] =
10477 0xffff0200, /* ps_2_0 */
10478 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10479 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10480 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10481 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10482 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10483 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10484 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10485 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10486 0x0000ffff
10488 static const DWORD pshader2_zw_code[] =
10490 0xffff0200, /* ps_2_0 */
10491 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10492 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10493 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10494 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10495 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10496 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10497 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10498 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10499 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10500 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10501 0x0000ffff
10503 static const DWORD vshader3_code[] =
10505 0xfffe0300, /* vs_3_0 */
10506 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10507 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10508 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10509 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10510 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10511 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10512 0x0000ffff
10514 static const DWORD vshader3_psize_code[] =
10516 0xfffe0300, /* vs_3_0 */
10517 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10518 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10519 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10520 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10521 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10522 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10523 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10524 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10525 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10526 0x0000ffff
10528 static const DWORD pshader3_code[] =
10530 0xffff0300, /* ps_3_0 */
10531 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10532 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10533 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10534 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10535 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10536 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10537 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10538 0x0000ffff
10540 static const DWORD pshader3_zw_code[] =
10542 0xffff0300, /* ps_3_0 */
10543 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10544 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10545 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10546 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10547 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10548 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10549 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10550 0x0000ffff
10552 static const struct test_shader
10554 DWORD version;
10555 const DWORD *code;
10557 novs = {0, NULL},
10558 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10559 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10560 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10561 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10562 nops = {0, NULL},
10563 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10564 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10565 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10566 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10567 ps3_zw = {D3DVS_VERSION(3, 0), pshader3_zw_code};
10568 static const struct
10570 const struct test_shader *vs;
10571 const struct test_shader *ps;
10572 DWORD accepted_fvf;
10573 unsigned int nonscaled_size, scaled_size;
10574 BOOL gives_0_0_texcoord;
10575 BOOL allow_broken;
10577 test_setups[] =
10579 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10580 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10581 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10582 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10583 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10584 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10585 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10586 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10587 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10588 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10589 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10590 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10591 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10593 static const struct
10595 BOOL zero_size;
10596 BOOL scale;
10597 BOOL override_min;
10598 DWORD fvf;
10599 const void *vertex_data;
10600 unsigned int vertex_size;
10602 tests[] =
10604 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10605 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10606 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10607 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10608 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10609 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10610 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10611 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10613 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10614 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10615 D3DMATRIX matrix =
10617 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10618 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10619 0.0f, 0.0f, 1.0f, 0.0f,
10620 -1.0f, 1.0f, 0.0f, 1.0f,
10621 }}};
10623 window = create_window();
10624 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10625 ok(!!d3d, "Failed to create a D3D object.\n");
10626 if (!(device = create_device(d3d, window, window, TRUE)))
10628 skip("Failed to create a D3D device, skipping tests.\n");
10629 goto done;
10632 memset(&caps, 0, sizeof(caps));
10633 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10634 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10635 if(caps.MaxPointSize < 32.0) {
10636 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10637 IDirect3DDevice9_Release(device);
10638 goto done;
10641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10642 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10644 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10645 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10647 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10648 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10650 hr = IDirect3DDevice9_BeginScene(device);
10651 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10653 ptsize = 15.0f;
10654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10655 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10657 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10659 ptsize = 31.0f;
10660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10661 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10663 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10665 ptsize = 30.75f;
10666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10667 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10668 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10669 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10671 if (caps.MaxPointSize >= 63.0f)
10673 ptsize = 63.0f;
10674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10675 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10677 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10679 ptsize = 62.75f;
10680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10681 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10683 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10686 ptsize = 1.0f;
10687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10688 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10690 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10692 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10693 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10694 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10695 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10697 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10698 ptsize = 15.0f;
10699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10700 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10701 ptsize = 1.0f;
10702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10703 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10705 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10708 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10710 /* pointsize < pointsize_min < pointsize_max?
10711 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10712 ptsize = 1.0f;
10713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10714 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10715 ptsize = 15.0f;
10716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10717 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10722 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10724 hr = IDirect3DDevice9_EndScene(device);
10725 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10727 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10728 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10729 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10731 if (caps.MaxPointSize >= 63.0)
10733 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10734 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10737 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10738 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10739 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10740 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10741 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10743 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10745 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10746 * generates texture coordinates for the point(result: Yes, it does)
10748 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10749 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10750 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10752 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10753 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10755 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10756 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10757 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10758 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10759 memset(&lr, 0, sizeof(lr));
10760 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10761 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10762 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10763 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10764 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10765 memset(&lr, 0, sizeof(lr));
10766 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10767 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10768 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10769 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10770 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10771 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10773 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10774 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10775 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10776 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10777 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10778 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10779 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10780 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10781 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10782 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10783 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10784 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10787 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10788 ptsize = 32.0;
10789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10790 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10792 hr = IDirect3DDevice9_BeginScene(device);
10793 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10795 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10796 hr = IDirect3DDevice9_EndScene(device);
10797 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10799 color = getPixelColor(device, 64-4, 64-4);
10800 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10801 color = getPixelColor(device, 64-4, 64+4);
10802 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10803 color = getPixelColor(device, 64+4, 64+4);
10804 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10805 color = getPixelColor(device, 64+4, 64-4);
10806 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10807 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10809 U(matrix).m[0][0] = 1.0f / 64.0f;
10810 U(matrix).m[1][1] = -1.0f / 64.0f;
10811 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10812 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10814 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10815 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10817 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10818 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10819 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10822 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10824 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10826 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10827 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10829 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10830 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10833 if (caps.MaxPointSize < 63.0f)
10835 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10836 goto cleanup;
10839 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10841 if (caps.VertexShaderVersion < test_setups[i].vs->version
10842 || caps.PixelShaderVersion < test_setups[i].ps->version)
10844 skip("Vertex / pixel shader version not supported, skipping test.\n");
10845 continue;
10847 if (test_setups[i].vs->code)
10849 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10850 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10852 else
10854 vs = NULL;
10856 if (test_setups[i].ps->code)
10858 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10859 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10861 else
10863 ps = NULL;
10866 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10867 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10868 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10869 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10871 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10873 BOOL allow_broken = test_setups[i].allow_broken;
10874 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10875 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10877 if (test_setups[i].accepted_fvf != tests[j].fvf)
10878 continue;
10880 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10882 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10884 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10886 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10889 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10891 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10892 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10894 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10895 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10897 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10899 hr = IDirect3DDevice9_BeginScene(device);
10900 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10902 tests[j].vertex_data, tests[j].vertex_size);
10903 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10904 hr = IDirect3DDevice9_EndScene(device);
10905 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10907 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10908 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10909 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10910 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10912 if (tests[j].zero_size)
10914 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10915 * it does the "useful" thing on all the drivers I tried. */
10916 /* On WARP it does draw some pixels, most of the time. */
10917 color = getPixelColor(device, 64, 64);
10918 ok(color_match(color, 0x0000ffff, 0)
10919 || broken(color_match(color, 0x00ff0000, 0))
10920 || broken(color_match(color, 0x00ffff00, 0))
10921 || broken(color_match(color, 0x00000000, 0))
10922 || broken(color_match(color, 0x0000ff00, 0)),
10923 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10925 else
10927 struct surface_readback rb;
10929 get_rt_readback(backbuffer, &rb);
10930 /* On AMD apparently only the first texcoord is modified by the point coordinates
10931 * when using SM2/3 pixel shaders. */
10932 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
10933 ok(color_match(color, 0x00ff0000, 0),
10934 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10935 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
10936 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10937 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10938 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10939 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
10940 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10941 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10942 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
10943 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10944 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10945 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10947 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
10948 ok(color_match(color, 0xff00ffff, 0),
10949 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10950 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
10951 ok(color_match(color, 0xff00ffff, 0),
10952 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10953 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
10954 ok(color_match(color, 0xff00ffff, 0),
10955 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10956 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
10957 ok(color_match(color, 0xff00ffff, 0),
10958 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10960 release_surface_readback(&rb);
10963 IDirect3DDevice9_SetVertexShader(device, NULL);
10964 IDirect3DDevice9_SetPixelShader(device, NULL);
10965 if (vs)
10966 IDirect3DVertexShader9_Release(vs);
10967 if (ps)
10968 IDirect3DVertexShader9_Release(ps);
10971 cleanup:
10972 IDirect3DSurface9_Release(backbuffer);
10973 IDirect3DSurface9_Release(rt);
10975 IDirect3DTexture9_Release(tex1);
10976 IDirect3DTexture9_Release(tex2);
10977 refcount = IDirect3DDevice9_Release(device);
10978 ok(!refcount, "Device has %u references left.\n", refcount);
10979 done:
10980 IDirect3D9_Release(d3d);
10981 DestroyWindow(window);
10984 static void multiple_rendertargets_test(void)
10986 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
10987 IDirect3DPixelShader9 *ps1, *ps2;
10988 IDirect3DTexture9 *tex1, *tex2;
10989 IDirect3DVertexShader9 *vs;
10990 IDirect3DDevice9 *device;
10991 IDirect3D9 *d3d;
10992 ULONG refcount;
10993 D3DCAPS9 caps;
10994 DWORD color;
10995 HWND window;
10996 HRESULT hr;
10997 UINT i, j;
10999 static const DWORD vshader_code[] =
11001 0xfffe0300, /* vs_3_0 */
11002 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11003 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11004 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11005 0x0000ffff /* end */
11007 static const DWORD pshader_code1[] =
11009 0xffff0300, /* ps_3_0 */
11010 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11011 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11012 0x0000ffff /* end */
11014 static const DWORD pshader_code2[] =
11016 0xffff0300, /* ps_3_0 */
11017 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11018 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11019 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11020 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11021 0x0000ffff /* end */
11023 static const float quad[] =
11025 -1.0f, -1.0f, 0.1f,
11026 -1.0f, 1.0f, 0.1f,
11027 1.0f, -1.0f, 0.1f,
11028 1.0f, 1.0f, 0.1f,
11030 static const float texquad[] =
11032 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11033 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11034 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11035 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11037 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11038 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11039 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11040 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11043 window = create_window();
11044 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11045 ok(!!d3d, "Failed to create a D3D object.\n");
11046 if (!(device = create_device(d3d, window, window, TRUE)))
11048 skip("Failed to create a D3D device, skipping tests.\n");
11049 goto done;
11052 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11053 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11054 if (caps.NumSimultaneousRTs < 2)
11056 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11057 IDirect3DDevice9_Release(device);
11058 goto done;
11060 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11062 skip("No shader model 3 support, skipping tests.\n");
11063 IDirect3DDevice9_Release(device);
11064 goto done;
11067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11068 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11070 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11071 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11072 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11074 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11075 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11076 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11077 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11078 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11079 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11080 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11081 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11082 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11083 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11084 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11085 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11087 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11088 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11089 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11090 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11091 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11092 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11094 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11095 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11097 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11098 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11100 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11101 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11104 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11105 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11106 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11107 color = getPixelColorFromSurface(readback, 8, 8);
11108 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11109 "Expected color 0x000000ff, got 0x%08x.\n", color);
11110 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11111 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11112 color = getPixelColorFromSurface(readback, 8, 8);
11113 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11114 "Expected color 0x000000ff, got 0x%08x.\n", color);
11116 /* Render targets not written by the pixel shader should be unmodified. */
11117 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11118 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11119 hr = IDirect3DDevice9_BeginScene(device);
11120 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11122 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11123 hr = IDirect3DDevice9_EndScene(device);
11124 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11125 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11126 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11127 color = getPixelColorFromSurface(readback, 8, 8);
11128 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11129 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11130 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11131 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11132 for (i = 6; i < 10; ++i)
11134 for (j = 6; j < 10; ++j)
11136 color = getPixelColorFromSurface(readback, j, i);
11137 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11138 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11143 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11144 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11145 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11146 color = getPixelColorFromSurface(readback, 8, 8);
11147 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11148 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11149 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11150 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11151 color = getPixelColorFromSurface(readback, 8, 8);
11152 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11153 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11155 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11156 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11158 hr = IDirect3DDevice9_BeginScene(device);
11159 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11161 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11162 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11165 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11166 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11167 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11168 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11169 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11170 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11171 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11172 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11173 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11174 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11175 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11177 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11178 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11182 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11183 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11184 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11185 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11187 hr = IDirect3DDevice9_EndScene(device);
11188 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11190 color = getPixelColor(device, 160, 240);
11191 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11192 color = getPixelColor(device, 480, 240);
11193 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11194 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11196 IDirect3DPixelShader9_Release(ps2);
11197 IDirect3DPixelShader9_Release(ps1);
11198 IDirect3DVertexShader9_Release(vs);
11199 IDirect3DTexture9_Release(tex1);
11200 IDirect3DTexture9_Release(tex2);
11201 IDirect3DSurface9_Release(surf1);
11202 IDirect3DSurface9_Release(surf2);
11203 IDirect3DSurface9_Release(backbuf);
11204 IDirect3DSurface9_Release(readback);
11205 refcount = IDirect3DDevice9_Release(device);
11206 ok(!refcount, "Device has %u references left.\n", refcount);
11207 done:
11208 IDirect3D9_Release(d3d);
11209 DestroyWindow(window);
11212 static void pixelshader_blending_test(void)
11214 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11215 IDirect3DTexture9 *offscreenTexture = NULL;
11216 IDirect3DDevice9 *device;
11217 IDirect3D9 *d3d;
11218 ULONG refcount;
11219 int fmt_index;
11220 DWORD color;
11221 HWND window;
11222 HRESULT hr;
11224 static const struct
11226 const char *fmtName;
11227 D3DFORMAT textureFormat;
11228 D3DCOLOR resultColorBlending;
11229 D3DCOLOR resultColorNoBlending;
11231 test_formats[] =
11233 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
11234 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11235 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
11236 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
11237 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11238 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
11239 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
11240 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
11242 static const float quad[][5] =
11244 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11245 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11246 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11247 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11249 static const struct
11251 struct vec3 position;
11252 DWORD diffuse;
11254 quad1[] =
11256 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
11257 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
11258 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
11259 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
11261 quad2[] =
11263 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11264 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11265 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11266 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11269 window = create_window();
11270 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11271 ok(!!d3d, "Failed to create a D3D object.\n");
11272 if (!(device = create_device(d3d, window, window, TRUE)))
11274 skip("Failed to create a D3D device, skipping tests.\n");
11275 goto done;
11278 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11279 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11281 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11283 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11285 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11286 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11288 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11289 continue;
11292 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11293 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11295 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11296 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11297 if(!offscreenTexture) {
11298 continue;
11301 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11302 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11303 if(!offscreen) {
11304 continue;
11307 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11308 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11310 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11311 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11312 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11313 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11314 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11315 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11316 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11317 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11321 /* Below we will draw two quads with different colors and try to blend
11322 * them together. The result color is compared with the expected
11323 * outcome. */
11324 hr = IDirect3DDevice9_BeginScene(device);
11325 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11327 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11328 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11330 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11333 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11335 /* Draw a quad using color 0x0010200. */
11336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11337 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11339 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11341 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11343 /* Draw a quad using color 0x0020100. */
11344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11345 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11347 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11349 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11351 /* We don't want to blend the result on the backbuffer. */
11352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11353 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11355 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11356 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11357 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11358 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11359 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11361 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11362 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11364 /* This time with the texture. */
11365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11366 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11368 hr = IDirect3DDevice9_EndScene(device);
11369 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11371 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11372 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11374 /* Compare the color of the center quad with our expectation. */
11375 color = getPixelColor(device, 320, 240);
11376 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11377 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11378 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11380 else
11382 /* No pixel shader blending is supported so expect garbage. The
11383 * type of 'garbage' depends on the driver version and OS. E.g. on
11384 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11385 * modern ones 0x002010ff which is also what NVIDIA reports. On
11386 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11387 color = getPixelColor(device, 320, 240);
11388 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11389 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11390 test_formats[fmt_index].fmtName, color);
11392 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11394 IDirect3DDevice9_SetTexture(device, 0, NULL);
11395 if(offscreenTexture) {
11396 IDirect3DTexture9_Release(offscreenTexture);
11398 if(offscreen) {
11399 IDirect3DSurface9_Release(offscreen);
11403 IDirect3DSurface9_Release(backbuffer);
11404 refcount = IDirect3DDevice9_Release(device);
11405 ok(!refcount, "Device has %u references left.\n", refcount);
11406 done:
11407 IDirect3D9_Release(d3d);
11408 DestroyWindow(window);
11411 static void tssargtemp_test(void)
11413 IDirect3DDevice9 *device;
11414 IDirect3D9 *d3d;
11415 D3DCOLOR color;
11416 ULONG refcount;
11417 D3DCAPS9 caps;
11418 HWND window;
11419 HRESULT hr;
11421 static const struct
11423 struct vec3 position;
11424 DWORD diffuse;
11426 quad[] =
11428 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11429 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11430 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11431 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11434 window = create_window();
11435 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11436 ok(!!d3d, "Failed to create a D3D object.\n");
11437 if (!(device = create_device(d3d, window, window, TRUE)))
11439 skip("Failed to create a D3D device, skipping tests.\n");
11440 goto done;
11443 memset(&caps, 0, sizeof(caps));
11444 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11445 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11446 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11447 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11448 IDirect3DDevice9_Release(device);
11449 goto done;
11452 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11453 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11455 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11456 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11457 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11458 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11460 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11461 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11462 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11463 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11464 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11465 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11467 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11468 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11469 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11470 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11471 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11472 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11474 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11475 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11478 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11480 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11481 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11482 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11484 hr = IDirect3DDevice9_BeginScene(device);
11485 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11488 hr = IDirect3DDevice9_EndScene(device);
11489 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11491 color = getPixelColor(device, 320, 240);
11492 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11493 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11495 refcount = IDirect3DDevice9_Release(device);
11496 ok(!refcount, "Device has %u references left.\n", refcount);
11497 done:
11498 IDirect3D9_Release(d3d);
11499 DestroyWindow(window);
11502 /* Drawing Indexed Geometry with instances*/
11503 static void stream_test(void)
11505 IDirect3DVertexDeclaration9 *pDecl = NULL;
11506 IDirect3DVertexShader9 *shader = NULL;
11507 IDirect3DVertexBuffer9 *vb3 = NULL;
11508 IDirect3DVertexBuffer9 *vb2 = NULL;
11509 IDirect3DVertexBuffer9 *vb = NULL;
11510 IDirect3DIndexBuffer9 *ib = NULL;
11511 IDirect3DDevice9 *device;
11512 IDirect3D9 *d3d;
11513 ULONG refcount;
11514 D3DCAPS9 caps;
11515 DWORD color;
11516 HWND window;
11517 unsigned i;
11518 HRESULT hr;
11519 BYTE *data;
11520 DWORD ind;
11522 static const struct testdata
11524 DWORD idxVertex; /* number of instances in the first stream */
11525 DWORD idxColor; /* number of instances in the second stream */
11526 DWORD idxInstance; /* should be 1 ?? */
11527 DWORD color1; /* color 1 instance */
11528 DWORD color2; /* color 2 instance */
11529 DWORD color3; /* color 3 instance */
11530 DWORD color4; /* color 4 instance */
11531 WORD strVertex; /* specify which stream to use 0-2*/
11532 WORD strColor;
11533 WORD strInstance;
11535 testcases[]=
11537 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11538 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11539 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11540 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11541 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11542 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11543 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11544 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11545 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11546 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11547 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11548 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11549 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11550 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11551 #if 0
11552 /* This draws one instance on some machines, no instance on others. */
11553 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11554 /* This case is handled in a stand alone test,
11555 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11556 * return D3DERR_INVALIDCALL. */
11557 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11558 #endif
11560 static const DWORD shader_code[] =
11562 0xfffe0101, /* vs_1_1 */
11563 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11564 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11565 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11566 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11567 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11568 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11569 0x0000ffff
11571 static const float quad[][3] =
11573 {-0.5f, -0.5f, 1.1f}, /*0 */
11574 {-0.5f, 0.5f, 1.1f}, /*1 */
11575 { 0.5f, -0.5f, 1.1f}, /*2 */
11576 { 0.5f, 0.5f, 1.1f}, /*3 */
11578 static const float vertcolor[][4] =
11580 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11581 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11582 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11583 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11585 /* 4 position for 4 instances */
11586 static const float instancepos[][3] =
11588 {-0.6f,-0.6f, 0.0f},
11589 { 0.6f,-0.6f, 0.0f},
11590 { 0.6f, 0.6f, 0.0f},
11591 {-0.6f, 0.6f, 0.0f},
11593 static const short indices[] = {0, 1, 2, 2, 1, 3};
11594 D3DVERTEXELEMENT9 decl[] =
11596 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11597 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11598 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11599 D3DDECL_END()
11602 window = create_window();
11603 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11604 ok(!!d3d, "Failed to create a D3D object.\n");
11605 if (!(device = create_device(d3d, window, window, TRUE)))
11607 skip("Failed to create a D3D device, skipping tests.\n");
11608 goto done;
11611 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11612 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11613 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11615 skip("No vs_3_0 support, skipping tests.\n");
11616 IDirect3DDevice9_Release(device);
11617 goto done;
11620 /* set the default value because it isn't done in wine? */
11621 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11622 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11624 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11625 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11626 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11628 /* check wrong cases */
11629 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11630 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11631 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11632 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11633 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11634 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11635 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11636 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11637 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11638 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11639 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11640 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11641 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11642 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11643 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11644 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11645 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11646 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11647 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11648 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11650 /* set the default value back */
11651 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11652 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11654 /* create all VertexBuffers*/
11655 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11656 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11657 if(!vb) {
11658 skip("Failed to create a vertex buffer\n");
11659 IDirect3DDevice9_Release(device);
11660 goto done;
11662 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11663 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11664 if(!vb2) {
11665 skip("Failed to create a vertex buffer\n");
11666 goto out;
11668 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11669 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11670 if(!vb3) {
11671 skip("Failed to create a vertex buffer\n");
11672 goto out;
11675 /* create IndexBuffer*/
11676 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11677 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11678 if(!ib) {
11679 skip("Failed to create an index buffer\n");
11680 goto out;
11683 /* copy all Buffers (Vertex + Index)*/
11684 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11685 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11686 memcpy(data, quad, sizeof(quad));
11687 hr = IDirect3DVertexBuffer9_Unlock(vb);
11688 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11689 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11690 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11691 memcpy(data, vertcolor, sizeof(vertcolor));
11692 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11693 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11694 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11695 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11696 memcpy(data, instancepos, sizeof(instancepos));
11697 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11698 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11699 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11700 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11701 memcpy(data, indices, sizeof(indices));
11702 hr = IDirect3DIndexBuffer9_Unlock(ib);
11703 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11705 /* create VertexShader */
11706 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11707 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11708 if(!shader) {
11709 skip("Failed to create a vertex shader.\n");
11710 goto out;
11713 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11714 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11716 hr = IDirect3DDevice9_SetIndices(device, ib);
11717 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11719 /* run all tests */
11720 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11722 struct testdata act = testcases[i];
11723 decl[0].Stream = act.strVertex;
11724 decl[1].Stream = act.strColor;
11725 decl[2].Stream = act.strInstance;
11726 /* create VertexDeclarations */
11727 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11728 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11730 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11731 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11733 hr = IDirect3DDevice9_BeginScene(device);
11734 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11736 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11737 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11739 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11740 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11741 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11742 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11743 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11745 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11746 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11747 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11748 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11749 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11751 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11752 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11753 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11754 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11755 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11757 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11758 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11759 hr = IDirect3DDevice9_EndScene(device);
11760 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11762 /* set all StreamSource && StreamSourceFreq back to default */
11763 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11764 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11765 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11766 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11767 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11768 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11769 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11770 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11771 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11772 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11773 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11774 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11776 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11777 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11779 color = getPixelColor(device, 160, 360);
11780 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11781 color = getPixelColor(device, 480, 360);
11782 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11783 color = getPixelColor(device, 480, 120);
11784 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11785 color = getPixelColor(device, 160, 120);
11786 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11792 out:
11793 if(vb) IDirect3DVertexBuffer9_Release(vb);
11794 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11795 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11796 if(ib)IDirect3DIndexBuffer9_Release(ib);
11797 if(shader)IDirect3DVertexShader9_Release(shader);
11798 refcount = IDirect3DDevice9_Release(device);
11799 ok(!refcount, "Device has %u references left.\n", refcount);
11800 done:
11801 IDirect3D9_Release(d3d);
11802 DestroyWindow(window);
11805 static void np2_stretch_rect_test(void)
11807 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11808 IDirect3DTexture9 *dsttex = NULL;
11809 IDirect3DDevice9 *device;
11810 IDirect3D9 *d3d;
11811 D3DCOLOR color;
11812 ULONG refcount;
11813 HWND window;
11814 HRESULT hr;
11816 static const D3DRECT r1 = {0, 0, 50, 50 };
11817 static const D3DRECT r2 = {50, 0, 100, 50 };
11818 static const D3DRECT r3 = {50, 50, 100, 100};
11819 static const D3DRECT r4 = {0, 50, 50, 100};
11820 static const float quad[] =
11822 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11823 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11824 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11825 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11828 window = create_window();
11829 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11830 ok(!!d3d, "Failed to create a D3D object.\n");
11831 if (!(device = create_device(d3d, window, window, TRUE)))
11833 skip("Failed to create a D3D device, skipping tests.\n");
11834 goto done;
11837 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11838 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11840 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11841 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11842 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11843 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11845 if(!src || !dsttex) {
11846 skip("One or more test resources could not be created\n");
11847 goto cleanup;
11850 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11851 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11853 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11854 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11856 /* Clear the StretchRect destination for debugging */
11857 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11858 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11860 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11862 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11863 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11865 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11866 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11867 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11868 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11869 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11871 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11872 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11874 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11875 * the target -> texture GL blit path
11877 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11878 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11879 IDirect3DSurface9_Release(dst);
11881 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11882 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11884 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11885 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11886 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11887 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11888 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11889 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11890 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11891 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11893 hr = IDirect3DDevice9_BeginScene(device);
11894 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11896 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11897 hr = IDirect3DDevice9_EndScene(device);
11898 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11900 color = getPixelColor(device, 160, 360);
11901 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11902 color = getPixelColor(device, 480, 360);
11903 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11904 color = getPixelColor(device, 480, 120);
11905 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11906 color = getPixelColor(device, 160, 120);
11907 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11908 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11909 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11911 cleanup:
11912 if(src) IDirect3DSurface9_Release(src);
11913 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11914 if(dsttex) IDirect3DTexture9_Release(dsttex);
11915 refcount = IDirect3DDevice9_Release(device);
11916 ok(!refcount, "Device has %u references left.\n", refcount);
11917 done:
11918 IDirect3D9_Release(d3d);
11919 DestroyWindow(window);
11922 static void texop_test(void)
11924 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11925 IDirect3DTexture9 *texture = NULL;
11926 D3DLOCKED_RECT locked_rect;
11927 IDirect3DDevice9 *device;
11928 IDirect3D9 *d3d;
11929 D3DCOLOR color;
11930 ULONG refcount;
11931 D3DCAPS9 caps;
11932 HWND window;
11933 HRESULT hr;
11934 unsigned i;
11936 static const struct {
11937 float x, y, z;
11938 float s, t;
11939 D3DCOLOR diffuse;
11940 } quad[] = {
11941 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11942 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11943 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11944 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11947 static const D3DVERTEXELEMENT9 decl_elements[] = {
11948 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11949 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11950 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11951 D3DDECL_END()
11954 static const struct {
11955 D3DTEXTUREOP op;
11956 const char *name;
11957 DWORD caps_flag;
11958 D3DCOLOR result;
11959 } test_data[] = {
11960 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11961 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
11962 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
11963 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
11964 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11965 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11966 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
11967 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11968 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11969 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11970 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11971 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
11972 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
11973 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11974 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11975 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
11976 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
11977 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11978 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
11979 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
11980 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
11981 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
11982 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
11985 window = create_window();
11986 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11987 ok(!!d3d, "Failed to create a D3D object.\n");
11988 if (!(device = create_device(d3d, window, window, TRUE)))
11990 skip("Failed to create a D3D device, skipping tests.\n");
11991 goto done;
11994 memset(&caps, 0, sizeof(caps));
11995 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11996 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11998 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11999 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12000 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12001 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12003 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12004 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12005 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12006 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12007 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12008 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12009 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12010 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12011 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12013 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12014 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12015 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12016 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12017 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12018 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12020 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12021 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12024 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12026 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12028 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12031 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12033 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12035 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12037 skip("tex operation %s not supported\n", test_data[i].name);
12038 continue;
12041 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12042 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12044 hr = IDirect3DDevice9_BeginScene(device);
12045 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12048 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12050 hr = IDirect3DDevice9_EndScene(device);
12051 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12053 color = getPixelColor(device, 320, 240);
12054 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12055 test_data[i].name, color, test_data[i].result);
12057 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12058 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12061 IDirect3DTexture9_Release(texture);
12062 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12063 refcount = IDirect3DDevice9_Release(device);
12064 ok(!refcount, "Device has %u references left.\n", refcount);
12065 done:
12066 IDirect3D9_Release(d3d);
12067 DestroyWindow(window);
12070 static void yuv_color_test(void)
12072 HRESULT hr;
12073 IDirect3DSurface9 *surface, *target;
12074 unsigned int i;
12075 D3DLOCKED_RECT lr;
12076 IDirect3D9 *d3d;
12077 D3DCOLOR color;
12078 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12079 IDirect3DDevice9 *device;
12080 D3DSURFACE_DESC desc;
12081 ULONG refcount;
12082 HWND window;
12084 static const struct
12086 DWORD in;
12087 D3DFORMAT format;
12088 const char *fmt_string;
12089 D3DCOLOR left, right;
12091 test_data[] =
12093 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12094 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12095 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12096 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12097 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12098 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12099 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12100 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12101 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12102 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12103 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12104 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12105 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12106 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12107 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12108 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12109 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12110 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12112 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12113 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12114 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12115 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12116 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12117 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12118 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12119 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12120 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12121 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12122 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12123 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12124 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12125 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12126 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12127 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12128 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12129 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12132 window = create_window();
12133 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12134 ok(!!d3d, "Failed to create a D3D object.\n");
12135 if (!(device = create_device(d3d, window, window, TRUE)))
12137 skip("Failed to create a D3D device, skipping tests.\n");
12138 goto done;
12141 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12142 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12143 hr = IDirect3DSurface9_GetDesc(target, &desc);
12144 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12146 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12148 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12149 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12150 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12151 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12153 if (skip_once != test_data[i].format)
12155 skip("%s is not supported.\n", test_data[i].fmt_string);
12156 skip_once = test_data[i].format;
12158 continue;
12160 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12161 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12163 if (skip_once != test_data[i].format)
12165 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12166 skip_once = test_data[i].format;
12168 continue;
12171 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12172 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12173 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12174 * second luminance value, resulting in an incorrect color in the right pixel. */
12175 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12176 D3DPOOL_DEFAULT, &surface, NULL);
12177 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12180 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12181 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12182 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12183 ((DWORD *)lr.pBits)[1] = 0x00800080;
12184 hr = IDirect3DSurface9_UnlockRect(surface);
12185 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12187 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12188 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12189 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12190 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12192 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12193 * although we asked for point filtering. Be careful when reading the results and use the pixel
12194 * centers. In the future we may want to add tests for the filtered pixels as well.
12196 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12197 * vastly differently, so we need a max diff of 18. */
12198 color = getPixelColor(device, 1, 240);
12199 ok(color_match(color, test_data[i].left, 18),
12200 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12201 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12202 color = getPixelColor(device, 318, 240);
12203 ok(color_match(color, test_data[i].right, 18),
12204 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12205 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12206 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12207 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12208 IDirect3DSurface9_Release(surface);
12211 IDirect3DSurface9_Release(target);
12212 refcount = IDirect3DDevice9_Release(device);
12213 ok(!refcount, "Device has %u references left.\n", refcount);
12214 done:
12215 IDirect3D9_Release(d3d);
12216 DestroyWindow(window);
12219 static void yuv_layout_test(void)
12221 HRESULT hr;
12222 IDirect3DSurface9 *surface, *target;
12223 unsigned int fmt, i, x, y;
12224 D3DFORMAT format;
12225 const char *fmt_string;
12226 D3DLOCKED_RECT lr;
12227 IDirect3D9 *d3d;
12228 D3DCOLOR color;
12229 DWORD ref_color;
12230 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12231 UINT width = 20, height = 16;
12232 IDirect3DDevice9 *device;
12233 ULONG refcount;
12234 D3DCAPS9 caps;
12235 D3DSURFACE_DESC desc;
12236 HWND window;
12238 static const struct
12240 DWORD color1, color2;
12241 DWORD rgb1, rgb2;
12243 test_data[] =
12245 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12246 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12247 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12248 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12249 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12250 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12251 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12252 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12255 static const struct
12257 D3DFORMAT format;
12258 const char *str;
12260 formats[] =
12262 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12263 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12264 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12265 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12268 window = create_window();
12269 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12270 ok(!!d3d, "Failed to create a D3D object.\n");
12271 if (!(device = create_device(d3d, window, window, TRUE)))
12273 skip("Failed to create a D3D device, skipping tests.\n");
12274 goto done;
12277 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12278 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12279 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12280 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12282 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12283 IDirect3DDevice9_Release(device);
12284 goto done;
12287 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12288 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12289 hr = IDirect3DSurface9_GetDesc(target, &desc);
12290 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12292 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12294 format = formats[fmt].format;
12295 fmt_string = formats[fmt].str;
12297 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12298 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12299 * of drawPrimitive. */
12300 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12301 D3DRTYPE_SURFACE, format) != D3D_OK)
12303 skip("%s is not supported.\n", fmt_string);
12304 continue;
12306 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12307 D3DDEVTYPE_HAL, format, desc.Format)))
12309 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12310 continue;
12313 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12314 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12316 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12318 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12319 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12320 buf = lr.pBits;
12321 chroma_buf = buf + lr.Pitch * height;
12322 if (format == MAKEFOURCC('Y','V','1','2'))
12324 v_buf = chroma_buf;
12325 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12327 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12328 for (y = 0; y < height; y++)
12330 for (x = 0; x < width; x += 2)
12332 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12333 BYTE Y = (color >> 16) & 0xff;
12334 BYTE U = (color >> 8) & 0xff;
12335 BYTE V = (color >> 0) & 0xff;
12336 if (format == D3DFMT_UYVY)
12338 buf[y * lr.Pitch + 2 * x + 0] = U;
12339 buf[y * lr.Pitch + 2 * x + 1] = Y;
12340 buf[y * lr.Pitch + 2 * x + 2] = V;
12341 buf[y * lr.Pitch + 2 * x + 3] = Y;
12343 else if (format == D3DFMT_YUY2)
12345 buf[y * lr.Pitch + 2 * x + 0] = Y;
12346 buf[y * lr.Pitch + 2 * x + 1] = U;
12347 buf[y * lr.Pitch + 2 * x + 2] = Y;
12348 buf[y * lr.Pitch + 2 * x + 3] = V;
12350 else if (format == MAKEFOURCC('Y','V','1','2'))
12352 buf[y * lr.Pitch + x + 0] = Y;
12353 buf[y * lr.Pitch + x + 1] = Y;
12354 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12355 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12357 else if (format == MAKEFOURCC('N','V','1','2'))
12359 buf[y * lr.Pitch + x + 0] = Y;
12360 buf[y * lr.Pitch + x + 1] = Y;
12361 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12362 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12366 hr = IDirect3DSurface9_UnlockRect(surface);
12367 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12370 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12371 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12372 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12374 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12375 * although we asked for point filtering. To prevent running into precision problems, read at points
12376 * with some margin within each quadrant.
12378 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12379 * vastly differently, so we need a max diff of 18. */
12380 for (y = 0; y < 4; y++)
12382 for (x = 0; x < 4; x++)
12384 UINT xcoord = (1 + 2 * x) * 640 / 8;
12385 UINT ycoord = (1 + 2 * y) * 480 / 8;
12386 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12387 color = getPixelColor(device, xcoord, ycoord);
12388 ok(color_match(color, ref_color, 18),
12389 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12390 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12393 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12395 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12397 IDirect3DSurface9_Release(surface);
12400 IDirect3DSurface9_Release(target);
12401 refcount = IDirect3DDevice9_Release(device);
12402 ok(!refcount, "Device has %u references left.\n", refcount);
12403 done:
12404 IDirect3D9_Release(d3d);
12405 DestroyWindow(window);
12408 static void texop_range_test(void)
12410 IDirect3DTexture9 *texture;
12411 D3DLOCKED_RECT locked_rect;
12412 IDirect3DDevice9 *device;
12413 IDirect3D9 *d3d;
12414 ULONG refcount;
12415 D3DCAPS9 caps;
12416 DWORD color;
12417 HWND window;
12418 HRESULT hr;
12420 static const struct
12422 float x, y, z;
12423 D3DCOLOR diffuse;
12425 quad[] =
12427 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12428 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12429 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12430 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12433 window = create_window();
12434 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12435 ok(!!d3d, "Failed to create a D3D object.\n");
12436 if (!(device = create_device(d3d, window, window, TRUE)))
12438 skip("Failed to create a D3D device, skipping tests.\n");
12439 goto done;
12442 /* We need ADD and SUBTRACT operations */
12443 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12444 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12445 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12447 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12448 IDirect3DDevice9_Release(device);
12449 goto done;
12451 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12453 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12454 IDirect3DDevice9_Release(device);
12455 goto done;
12458 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12459 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12461 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12462 /* Stage 1: result = diffuse(=1.0) + diffuse
12463 * stage 2: result = result - tfactor(= 0.5)
12465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12466 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12467 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12468 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12469 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12470 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12471 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12472 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12473 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12474 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12475 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12476 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12477 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12478 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12481 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12482 hr = IDirect3DDevice9_BeginScene(device);
12483 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12485 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12486 hr = IDirect3DDevice9_EndScene(device);
12487 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12489 color = getPixelColor(device, 320, 240);
12490 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12491 color);
12492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12493 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12495 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12496 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12497 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12498 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12499 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12500 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12501 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12502 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12503 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12505 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12506 * stage 2: result = result + diffuse(1.0)
12508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12509 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12510 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12511 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12512 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12513 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12514 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12515 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12516 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12517 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12518 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12519 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12520 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12521 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12523 hr = IDirect3DDevice9_BeginScene(device);
12524 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12526 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12527 hr = IDirect3DDevice9_EndScene(device);
12528 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12530 color = getPixelColor(device, 320, 240);
12531 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12532 color);
12533 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12534 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12536 IDirect3DTexture9_Release(texture);
12537 refcount = IDirect3DDevice9_Release(device);
12538 ok(!refcount, "Device has %u references left.\n", refcount);
12539 done:
12540 IDirect3D9_Release(d3d);
12541 DestroyWindow(window);
12544 static void alphareplicate_test(void)
12546 IDirect3DDevice9 *device;
12547 IDirect3D9 *d3d;
12548 ULONG refcount;
12549 DWORD color;
12550 HWND window;
12551 HRESULT hr;
12553 static const struct
12555 struct vec3 position;
12556 DWORD diffuse;
12558 quad[] =
12560 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12561 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12562 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12563 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12566 window = create_window();
12567 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12568 ok(!!d3d, "Failed to create a D3D object.\n");
12569 if (!(device = create_device(d3d, window, window, TRUE)))
12571 skip("Failed to create a D3D device, skipping tests.\n");
12572 goto done;
12575 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12576 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12578 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12579 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12581 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12582 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12583 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12584 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12586 hr = IDirect3DDevice9_BeginScene(device);
12587 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12589 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12590 hr = IDirect3DDevice9_EndScene(device);
12591 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12593 color = getPixelColor(device, 320, 240);
12594 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12595 color);
12596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12597 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12599 refcount = IDirect3DDevice9_Release(device);
12600 ok(!refcount, "Device has %u references left.\n", refcount);
12601 done:
12602 IDirect3D9_Release(d3d);
12603 DestroyWindow(window);
12606 static void dp3_alpha_test(void)
12608 IDirect3DDevice9 *device;
12609 IDirect3D9 *d3d;
12610 ULONG refcount;
12611 D3DCAPS9 caps;
12612 DWORD color;
12613 HWND window;
12614 HRESULT hr;
12616 static const struct
12618 struct vec3 position;
12619 DWORD diffuse;
12621 quad[] =
12623 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12624 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12625 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12626 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12629 window = create_window();
12630 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12631 ok(!!d3d, "Failed to create a D3D object.\n");
12632 if (!(device = create_device(d3d, window, window, TRUE)))
12634 skip("Failed to create a D3D device, skipping tests.\n");
12635 goto done;
12638 memset(&caps, 0, sizeof(caps));
12639 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12640 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12641 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12643 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12644 IDirect3DDevice9_Release(device);
12645 goto done;
12648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12649 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12651 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12652 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12654 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12655 * mov r0.a, diffuse.a
12656 * mov r0, r0.a
12658 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12659 * 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
12660 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12662 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12663 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12664 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12665 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12666 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12667 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12668 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12669 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12671 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12672 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12674 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12675 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12676 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12677 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12679 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12681 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12683 hr = IDirect3DDevice9_BeginScene(device);
12684 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12685 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12686 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12687 hr = IDirect3DDevice9_EndScene(device);
12688 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12690 color = getPixelColor(device, 320, 240);
12691 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12692 color);
12693 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12694 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12696 refcount = IDirect3DDevice9_Release(device);
12697 ok(!refcount, "Device has %u references left.\n", refcount);
12698 done:
12699 IDirect3D9_Release(d3d);
12700 DestroyWindow(window);
12703 static void zwriteenable_test(void)
12705 IDirect3DDevice9 *device;
12706 IDirect3D9 *d3d;
12707 D3DCOLOR color;
12708 ULONG refcount;
12709 HWND window;
12710 HRESULT hr;
12712 static const struct
12714 struct vec3 position;
12715 DWORD diffuse;
12717 quad1[] =
12719 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12720 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12721 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12722 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12724 quad2[] =
12726 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12727 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12728 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12729 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12732 window = create_window();
12733 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12734 ok(!!d3d, "Failed to create a D3D object.\n");
12735 if (!(device = create_device(d3d, window, window, TRUE)))
12737 skip("Failed to create a D3D device, skipping tests.\n");
12738 goto done;
12741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12744 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12745 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12747 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12749 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12751 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12753 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12755 hr = IDirect3DDevice9_BeginScene(device);
12756 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12757 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12758 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12759 * because the z test is disabled. The question is whether the z = 0.1
12760 * values are written into the Z buffer. After the draw, set
12761 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12762 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12763 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12764 * green color is written. It turns out that the screen is green, so
12765 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12766 * buffer. */
12767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12768 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12770 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12771 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12772 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12773 hr = IDirect3DDevice9_EndScene(device);
12774 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12776 color = getPixelColor(device, 320, 240);
12777 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12778 color);
12779 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12780 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12782 refcount = IDirect3DDevice9_Release(device);
12783 ok(!refcount, "Device has %u references left.\n", refcount);
12784 done:
12785 IDirect3D9_Release(d3d);
12786 DestroyWindow(window);
12789 static void alphatest_test(void)
12791 #define ALPHATEST_PASSED 0x0000ff00
12792 #define ALPHATEST_FAILED 0x00ff0000
12793 IDirect3DDevice9 *device;
12794 unsigned int i, j;
12795 IDirect3D9 *d3d;
12796 D3DCOLOR color;
12797 ULONG refcount;
12798 D3DCAPS9 caps;
12799 HWND window;
12800 HRESULT hr;
12802 static const struct
12804 D3DCMPFUNC func;
12805 D3DCOLOR color_less;
12806 D3DCOLOR color_equal;
12807 D3DCOLOR color_greater;
12809 testdata[] =
12811 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12812 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12813 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12814 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12815 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12816 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12817 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12818 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12820 static const struct
12822 struct vec3 position;
12823 DWORD diffuse;
12825 quad[] =
12827 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12828 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12829 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12830 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12833 window = create_window();
12834 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12835 ok(!!d3d, "Failed to create a D3D object.\n");
12836 if (!(device = create_device(d3d, window, window, TRUE)))
12838 skip("Failed to create a D3D device, skipping tests.\n");
12839 goto done;
12842 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12843 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12846 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12849 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12850 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12852 for (j = 0; j < 2; ++j)
12854 if (j == 1)
12856 /* Try a pixel shader instead of fixed function. The wined3d code
12857 * may emulate the alpha test either for performance reasons
12858 * (floating point RTs) or to work around driver bugs (GeForce
12859 * 7x00 cards on MacOS). There may be a different codepath for ffp
12860 * and shader in this case, and the test should cover both. */
12861 IDirect3DPixelShader9 *ps;
12862 static const DWORD shader_code[] =
12864 0xffff0101, /* ps_1_1 */
12865 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12866 0x0000ffff /* end */
12868 memset(&caps, 0, sizeof(caps));
12869 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12870 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12871 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12872 break;
12875 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12876 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12877 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12878 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12879 IDirect3DPixelShader9_Release(ps);
12882 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12887 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12890 hr = IDirect3DDevice9_BeginScene(device);
12891 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12893 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12894 hr = IDirect3DDevice9_EndScene(device);
12895 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12896 color = getPixelColor(device, 320, 240);
12897 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12898 color, testdata[i].color_less, testdata[i].func);
12899 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12900 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12902 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12903 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12905 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12906 hr = IDirect3DDevice9_BeginScene(device);
12907 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12908 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12909 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12910 hr = IDirect3DDevice9_EndScene(device);
12911 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12912 color = getPixelColor(device, 320, 240);
12913 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12914 color, testdata[i].color_equal, testdata[i].func);
12915 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12916 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12921 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12922 hr = IDirect3DDevice9_BeginScene(device);
12923 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12925 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12926 hr = IDirect3DDevice9_EndScene(device);
12927 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12928 color = getPixelColor(device, 320, 240);
12929 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12930 color, testdata[i].color_greater, testdata[i].func);
12931 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12932 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12936 refcount = IDirect3DDevice9_Release(device);
12937 ok(!refcount, "Device has %u references left.\n", refcount);
12938 done:
12939 IDirect3D9_Release(d3d);
12940 DestroyWindow(window);
12943 static void sincos_test(void)
12945 IDirect3DVertexShader9 *sin_shader, *cos_shader;
12946 IDirect3DDevice9 *device;
12947 struct vec3 data[1280];
12948 IDirect3D9 *d3d;
12949 unsigned int i;
12950 ULONG refcount;
12951 D3DCAPS9 caps;
12952 HWND window;
12953 HRESULT hr;
12955 static const DWORD sin_shader_code[] =
12957 0xfffe0200, /* vs_2_0 */
12958 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12959 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12960 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12961 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
12962 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12963 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
12964 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
12965 0x0000ffff /* end */
12967 static const DWORD cos_shader_code[] =
12969 0xfffe0200, /* vs_2_0 */
12970 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12971 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12972 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12973 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
12974 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12975 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
12976 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
12977 0x0000ffff /* end */
12979 static const float sincosc1[4] = {D3DSINCOSCONST1};
12980 static const float sincosc2[4] = {D3DSINCOSCONST2};
12982 window = create_window();
12983 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12984 ok(!!d3d, "Failed to create a D3D object.\n");
12985 if (!(device = create_device(d3d, window, window, TRUE)))
12987 skip("Failed to create a D3D device, skipping tests.\n");
12988 goto done;
12991 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12992 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12993 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12995 skip("No vs_2_0 support, skipping tests.\n");
12996 IDirect3DDevice9_Release(device);
12997 goto done;
13000 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13001 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13003 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13005 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13006 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13007 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13008 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13009 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13010 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13011 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13012 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13014 /* Generate a point from -1 to 1 every 0.5 pixels */
13015 for(i = 0; i < 1280; i++) {
13016 data[i].x = (-640.0 + i) / 640.0;
13017 data[i].y = 0.0;
13018 data[i].z = 0.1;
13021 hr = IDirect3DDevice9_BeginScene(device);
13022 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13024 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13025 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13027 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13029 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13030 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13032 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13034 hr = IDirect3DDevice9_EndScene(device);
13035 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13037 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13038 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13039 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13041 IDirect3DVertexShader9_Release(sin_shader);
13042 IDirect3DVertexShader9_Release(cos_shader);
13043 refcount = IDirect3DDevice9_Release(device);
13044 ok(!refcount, "Device has %u references left.\n", refcount);
13045 done:
13046 IDirect3D9_Release(d3d);
13047 DestroyWindow(window);
13050 static void loop_index_test(void)
13052 IDirect3DVertexShader9 *shader;
13053 IDirect3DDevice9 *device;
13054 IDirect3D9 *d3d;
13055 float values[4];
13056 ULONG refcount;
13057 D3DCAPS9 caps;
13058 DWORD color;
13059 HWND window;
13060 HRESULT hr;
13062 static const DWORD shader_code[] =
13064 0xfffe0200, /* vs_2_0 */
13065 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13066 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13067 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13068 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13069 0x0000001d, /* endloop */
13070 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13071 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13072 0x0000ffff /* END */
13074 static const float quad[] =
13076 -1.0f, -1.0f, 0.1f,
13077 -1.0f, 1.0f, 0.1f,
13078 1.0f, -1.0f, 0.1f,
13079 1.0f, 1.0f, 0.1f,
13081 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13082 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13083 static const int i0[4] = {2, 10, -3, 0};
13085 window = create_window();
13086 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13087 ok(!!d3d, "Failed to create a D3D object.\n");
13088 if (!(device = create_device(d3d, window, window, TRUE)))
13090 skip("Failed to create a D3D device, skipping tests.\n");
13091 goto done;
13094 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13095 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13096 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13098 skip("No vs_2_0 support, skipping tests.\n");
13099 IDirect3DDevice9_Release(device);
13100 goto done;
13103 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13104 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13105 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13106 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13107 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13108 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13112 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13114 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13115 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13116 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13117 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13118 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13119 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13120 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13121 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13122 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13123 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13124 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13125 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13126 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13127 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13128 values[0] = 1.0;
13129 values[1] = 1.0;
13130 values[2] = 0.0;
13131 values[3] = 0.0;
13132 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13133 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13134 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13135 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13136 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13137 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13138 values[0] = -1.0;
13139 values[1] = 0.0;
13140 values[2] = 0.0;
13141 values[3] = 0.0;
13142 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13143 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13144 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13145 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13146 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13148 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13149 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13150 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13151 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13153 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13154 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13156 hr = IDirect3DDevice9_BeginScene(device);
13157 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13159 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13160 hr = IDirect3DDevice9_EndScene(device);
13161 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13162 color = getPixelColor(device, 320, 240);
13163 ok(color_match(color, 0x0000ff00, 1),
13164 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13165 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13166 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13168 IDirect3DVertexShader9_Release(shader);
13169 refcount = IDirect3DDevice9_Release(device);
13170 ok(!refcount, "Device has %u references left.\n", refcount);
13171 done:
13172 IDirect3D9_Release(d3d);
13173 DestroyWindow(window);
13176 static void sgn_test(void)
13178 IDirect3DVertexShader9 *shader;
13179 IDirect3DDevice9 *device;
13180 IDirect3D9 *d3d;
13181 ULONG refcount;
13182 D3DCAPS9 caps;
13183 DWORD color;
13184 HWND window;
13185 HRESULT hr;
13187 static const DWORD shader_code[] =
13189 0xfffe0200, /* vs_2_0 */
13190 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13191 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13192 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13193 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13194 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13195 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13196 0x0000ffff /* end */
13198 static const float quad[] =
13200 -1.0f, -1.0f, 0.1f,
13201 -1.0f, 1.0f, 0.1f,
13202 1.0f, -1.0f, 0.1f,
13203 1.0f, 1.0f, 0.1f,
13206 window = create_window();
13207 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13208 ok(!!d3d, "Failed to create a D3D object.\n");
13209 if (!(device = create_device(d3d, window, window, TRUE)))
13211 skip("Failed to create a D3D device, skipping tests.\n");
13212 goto done;
13215 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13216 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13217 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13219 skip("No vs_2_0 support, skipping tests.\n");
13220 IDirect3DDevice9_Release(device);
13221 goto done;
13224 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13225 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13226 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13227 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13228 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13229 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13231 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\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, 0x008000ff, 1),
13241 "sgn test returned color 0x%08x, expected 0x008000ff\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 viewport_test(void)
13255 IDirect3DDevice9 *device;
13256 BOOL draw_failed = TRUE;
13257 D3DVIEWPORT9 vp;
13258 IDirect3D9 *d3d;
13259 ULONG refcount;
13260 DWORD color;
13261 HWND window;
13262 HRESULT hr;
13264 static const float quad[] =
13266 -0.5f, -0.5f, 0.1f,
13267 -0.5f, 0.5f, 0.1f,
13268 0.5f, -0.5f, 0.1f,
13269 0.5f, 0.5f, 0.1f,
13272 window = create_window();
13273 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13274 ok(!!d3d, "Failed to create a D3D object.\n");
13275 if (!(device = create_device(d3d, window, window, TRUE)))
13277 skip("Failed to create a D3D device, skipping tests.\n");
13278 goto done;
13281 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13282 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13284 /* Test a viewport with Width and Height bigger than the surface dimensions
13286 * TODO: Test Width < surface.width, but X + Width > surface.width
13287 * TODO: Test Width < surface.width, what happens with the height?
13289 * The expected behavior is that the viewport behaves like the "default"
13290 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13291 * MinZ = 0.0, MaxZ = 1.0.
13293 * Starting with Windows 7 the behavior among driver versions is not
13294 * consistent. The SetViewport call is accepted on all drivers. Some
13295 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13296 * nvidia drivers draw, but use the actual values in the viewport and only
13297 * display the upper left part on the surface.
13299 memset(&vp, 0, sizeof(vp));
13300 vp.X = 0;
13301 vp.Y = 0;
13302 vp.Width = 10000;
13303 vp.Height = 10000;
13304 vp.MinZ = 0.0;
13305 vp.MaxZ = 0.0;
13306 hr = IDirect3DDevice9_SetViewport(device, &vp);
13307 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13310 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13312 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13313 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13314 hr = IDirect3DDevice9_BeginScene(device);
13315 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13317 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13318 draw_failed = FAILED(hr);
13319 hr = IDirect3DDevice9_EndScene(device);
13320 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13322 if(!draw_failed)
13324 color = getPixelColor(device, 158, 118);
13325 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13326 color = getPixelColor(device, 162, 118);
13327 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13328 color = getPixelColor(device, 158, 122);
13329 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13330 color = getPixelColor(device, 162, 122);
13331 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13333 color = getPixelColor(device, 478, 358);
13334 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13335 color = getPixelColor(device, 482, 358);
13336 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13337 color = getPixelColor(device, 478, 362);
13338 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13339 color = getPixelColor(device, 482, 362);
13340 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13343 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13344 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13346 refcount = IDirect3DDevice9_Release(device);
13347 ok(!refcount, "Device has %u references left.\n", refcount);
13348 done:
13349 IDirect3D9_Release(d3d);
13350 DestroyWindow(window);
13353 /* This test tests depth clamping / clipping behaviour:
13354 * - With software vertex processing, depth values are clamped to the
13355 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13356 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13357 * same as regular vertices here.
13358 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13359 * Normal vertices are always clipped. Pretransformed vertices are
13360 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13361 * - The viewport's MinZ/MaxZ is irrelevant for this.
13363 static void depth_clamp_test(void)
13365 IDirect3DDevice9 *device;
13366 D3DVIEWPORT9 vp;
13367 IDirect3D9 *d3d;
13368 D3DCOLOR color;
13369 ULONG refcount;
13370 D3DCAPS9 caps;
13371 HWND window;
13372 HRESULT hr;
13374 static const struct
13376 struct vec4 position;
13377 DWORD diffuse;
13379 quad1[] =
13381 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13382 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13383 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13384 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13386 quad2[] =
13388 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13389 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13390 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13391 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13393 quad3[] =
13395 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13396 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13397 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13398 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13400 quad4[] =
13402 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13403 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13404 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13405 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13407 static const struct
13409 struct vec3 position;
13410 DWORD diffuse;
13412 quad5[] =
13414 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13415 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13416 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13417 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13419 quad6[] =
13421 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13422 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13423 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13424 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13427 window = create_window();
13428 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13429 ok(!!d3d, "Failed to create a D3D object.\n");
13430 if (!(device = create_device(d3d, window, window, TRUE)))
13432 skip("Failed to create a D3D device, skipping tests.\n");
13433 goto done;
13436 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13437 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13439 vp.X = 0;
13440 vp.Y = 0;
13441 vp.Width = 640;
13442 vp.Height = 480;
13443 vp.MinZ = 0.0;
13444 vp.MaxZ = 7.5;
13446 hr = IDirect3DDevice9_SetViewport(device, &vp);
13447 if(FAILED(hr))
13449 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13450 * the tests because the 7.5 is just intended to show that it doesn't have
13451 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13452 * viewport and continue.
13454 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13455 vp.MaxZ = 1.0;
13456 hr = IDirect3DDevice9_SetViewport(device, &vp);
13458 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13461 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13464 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13466 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13467 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13468 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13470 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13472 hr = IDirect3DDevice9_BeginScene(device);
13473 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13475 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13476 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13479 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13481 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13484 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13487 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13489 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13491 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13492 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13494 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13495 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13497 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13498 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13501 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13504 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13506 hr = IDirect3DDevice9_EndScene(device);
13507 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13509 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13511 color = getPixelColor(device, 75, 75);
13512 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13513 color = getPixelColor(device, 150, 150);
13514 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13515 color = getPixelColor(device, 320, 240);
13516 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13517 color = getPixelColor(device, 320, 330);
13518 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13519 color = getPixelColor(device, 320, 330);
13520 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13522 else
13524 color = getPixelColor(device, 75, 75);
13525 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13526 color = getPixelColor(device, 150, 150);
13527 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13528 color = getPixelColor(device, 320, 240);
13529 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13530 color = getPixelColor(device, 320, 330);
13531 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13532 color = getPixelColor(device, 320, 330);
13533 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13536 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13537 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13539 refcount = IDirect3DDevice9_Release(device);
13540 ok(!refcount, "Device has %u references left.\n", refcount);
13541 done:
13542 IDirect3D9_Release(d3d);
13543 DestroyWindow(window);
13546 static void depth_bounds_test(void)
13548 static const struct
13550 struct vec4 position;
13551 DWORD diffuse;
13553 quad1[] =
13555 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13556 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13557 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13558 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13560 quad2[] =
13562 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13563 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13564 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13565 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13567 quad3[] =
13569 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13570 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13571 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13572 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13575 union {
13576 DWORD d;
13577 float f;
13578 } tmpvalue;
13580 IDirect3DSurface9 *offscreen_surface = NULL;
13581 IDirect3DDevice9 *device;
13582 IDirect3D9 *d3d;
13583 D3DCOLOR color;
13584 ULONG refcount;
13585 HWND window;
13586 HRESULT hr;
13588 window = create_window();
13589 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13590 ok(!!d3d, "Failed to create a D3D object.\n");
13591 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13592 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13594 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13595 goto done;
13597 if (!(device = create_device(d3d, window, window, TRUE)))
13599 skip("Failed to create a D3D device, skipping tests.\n");
13600 goto done;
13603 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13604 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13605 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13606 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13608 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13609 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13612 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13614 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13616 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13618 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13621 hr = IDirect3DDevice9_BeginScene(device);
13622 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13624 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13625 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13628 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13631 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13633 tmpvalue.f = 0.625;
13634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13635 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13637 tmpvalue.f = 0.75;
13638 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13639 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13642 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13644 tmpvalue.f = 0.75;
13645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13646 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13649 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13652 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13654 hr = IDirect3DDevice9_EndScene(device);
13655 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13657 color = getPixelColor(device, 150, 130);
13658 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13659 color = getPixelColor(device, 150, 200);
13660 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13661 color = getPixelColor(device, 150, 300-5);
13662 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13663 color = getPixelColor(device, 150, 300+5);
13664 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13665 color = getPixelColor(device, 150, 330);
13666 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13667 color = getPixelColor(device, 150, 360-5);
13668 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13669 color = getPixelColor(device, 150, 360+5);
13670 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13672 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13673 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13674 refcount = IDirect3DDevice9_Release(device);
13675 ok(!refcount, "Device has %u references left.\n", refcount);
13676 done:
13677 IDirect3D9_Release(d3d);
13678 DestroyWindow(window);
13681 static void depth_buffer_test(void)
13683 static const struct
13685 struct vec3 position;
13686 DWORD diffuse;
13688 quad1[] =
13690 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13691 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13692 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13693 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13695 quad2[] =
13697 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13698 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13699 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13700 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13702 quad3[] =
13704 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13705 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13706 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13707 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13709 static const DWORD expected_colors[4][4] =
13711 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13712 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13713 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13714 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13717 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13718 IDirect3DDevice9 *device;
13719 unsigned int i, j;
13720 D3DVIEWPORT9 vp;
13721 IDirect3D9 *d3d;
13722 D3DCOLOR color;
13723 ULONG refcount;
13724 HWND window;
13725 HRESULT hr;
13727 window = create_window();
13728 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13729 ok(!!d3d, "Failed to create a D3D object.\n");
13730 if (!(device = create_device(d3d, window, window, TRUE)))
13732 skip("Failed to create a D3D device, skipping tests.\n");
13733 goto done;
13736 vp.X = 0;
13737 vp.Y = 0;
13738 vp.Width = 640;
13739 vp.Height = 480;
13740 vp.MinZ = 0.0;
13741 vp.MaxZ = 1.0;
13743 hr = IDirect3DDevice9_SetViewport(device, &vp);
13744 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13747 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13749 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13751 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13753 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13754 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13755 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13757 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13758 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13759 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13760 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13761 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13762 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13763 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13764 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13765 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13766 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13767 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13769 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13770 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13772 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13774 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13775 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13777 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13779 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13780 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13782 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13784 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13785 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13786 hr = IDirect3DDevice9_BeginScene(device);
13787 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13789 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13790 hr = IDirect3DDevice9_EndScene(device);
13791 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13793 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13794 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13797 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13799 hr = IDirect3DDevice9_BeginScene(device);
13800 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13802 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13804 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13805 hr = IDirect3DDevice9_EndScene(device);
13806 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13808 for (i = 0; i < 4; ++i)
13810 for (j = 0; j < 4; ++j)
13812 unsigned int x = 80 * ((2 * j) + 1);
13813 unsigned int y = 60 * ((2 * i) + 1);
13814 color = getPixelColor(device, x, y);
13815 ok(color_match(color, expected_colors[i][j], 0),
13816 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13821 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13823 IDirect3DSurface9_Release(backbuffer);
13824 IDirect3DSurface9_Release(rt3);
13825 IDirect3DSurface9_Release(rt2);
13826 IDirect3DSurface9_Release(rt1);
13827 refcount = IDirect3DDevice9_Release(device);
13828 ok(!refcount, "Device has %u references left.\n", refcount);
13829 done:
13830 IDirect3D9_Release(d3d);
13831 DestroyWindow(window);
13834 /* Test that partial depth copies work the way they're supposed to. The clear
13835 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13836 * the following draw should only copy back the part that was modified. */
13837 static void depth_buffer2_test(void)
13839 static const struct
13841 struct vec3 position;
13842 DWORD diffuse;
13844 quad[] =
13846 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13847 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13848 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13849 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13852 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13853 IDirect3DDevice9 *device;
13854 unsigned int i, j;
13855 D3DVIEWPORT9 vp;
13856 IDirect3D9 *d3d;
13857 D3DCOLOR color;
13858 ULONG refcount;
13859 HWND window;
13860 HRESULT hr;
13862 window = create_window();
13863 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13864 ok(!!d3d, "Failed to create a D3D object.\n");
13865 if (!(device = create_device(d3d, window, window, TRUE)))
13867 skip("Failed to create a D3D device, skipping tests.\n");
13868 goto done;
13871 vp.X = 0;
13872 vp.Y = 0;
13873 vp.Width = 640;
13874 vp.Height = 480;
13875 vp.MinZ = 0.0;
13876 vp.MaxZ = 1.0;
13878 hr = IDirect3DDevice9_SetViewport(device, &vp);
13879 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13882 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13884 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13886 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13887 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13888 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13889 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13890 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13892 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13893 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13894 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13895 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13896 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13897 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13898 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13899 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13901 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13902 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13903 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13904 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13906 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13907 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13908 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13909 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13911 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13912 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13914 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13916 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13917 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13920 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13922 hr = IDirect3DDevice9_BeginScene(device);
13923 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13925 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13926 hr = IDirect3DDevice9_EndScene(device);
13927 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13929 for (i = 0; i < 4; ++i)
13931 for (j = 0; j < 4; ++j)
13933 unsigned int x = 80 * ((2 * j) + 1);
13934 unsigned int y = 60 * ((2 * i) + 1);
13935 color = getPixelColor(device, x, y);
13936 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
13937 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
13941 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13942 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13944 IDirect3DSurface9_Release(backbuffer);
13945 IDirect3DSurface9_Release(rt2);
13946 IDirect3DSurface9_Release(rt1);
13947 refcount = IDirect3DDevice9_Release(device);
13948 ok(!refcount, "Device has %u references left.\n", refcount);
13949 done:
13950 IDirect3D9_Release(d3d);
13951 DestroyWindow(window);
13954 static void depth_blit_test(void)
13956 static const struct
13958 struct vec3 position;
13959 DWORD diffuse;
13961 quad1[] =
13963 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
13964 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
13965 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
13966 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
13968 quad2[] =
13970 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
13971 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
13972 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
13973 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
13975 static const DWORD expected_colors[4][4] =
13977 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13978 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13979 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13980 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13983 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
13984 IDirect3DDevice9 *device;
13985 RECT src_rect, dst_rect;
13986 unsigned int i, j;
13987 D3DVIEWPORT9 vp;
13988 IDirect3D9 *d3d;
13989 D3DCOLOR color;
13990 ULONG refcount;
13991 HWND window;
13992 HRESULT hr;
13994 window = create_window();
13995 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13996 ok(!!d3d, "Failed to create a D3D object.\n");
13997 if (!(device = create_device(d3d, window, window, TRUE)))
13999 skip("Failed to create a D3D device, skipping tests.\n");
14000 goto done;
14003 vp.X = 0;
14004 vp.Y = 0;
14005 vp.Width = 640;
14006 vp.Height = 480;
14007 vp.MinZ = 0.0;
14008 vp.MaxZ = 1.0;
14010 hr = IDirect3DDevice9_SetViewport(device, &vp);
14011 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14013 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14014 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14015 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14016 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14017 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14018 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14019 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14020 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14021 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14022 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14025 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14027 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14028 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14029 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14030 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14031 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14034 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14035 SetRect(&dst_rect, 0, 0, 480, 360);
14036 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14037 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14038 SetRect(&dst_rect, 0, 0, 320, 240);
14039 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14040 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14042 /* Partial blit. */
14043 SetRect(&src_rect, 0, 0, 320, 240);
14044 SetRect(&dst_rect, 0, 0, 320, 240);
14045 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14046 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14047 /* Flipped. */
14048 SetRect(&src_rect, 0, 0, 640, 480);
14049 SetRect(&dst_rect, 0, 480, 640, 0);
14050 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14051 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14052 /* Full, explicit. */
14053 SetRect(&src_rect, 0, 0, 640, 480);
14054 SetRect(&dst_rect, 0, 0, 640, 480);
14055 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14056 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14057 /* Filtered blit. */
14058 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14059 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14060 /* Depth -> color blit.*/
14061 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14062 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14063 IDirect3DSurface9_Release(backbuffer);
14064 /* Full surface, different sizes */
14065 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14066 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14067 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14068 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14070 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14071 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14073 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14074 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14075 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14078 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14079 hr = IDirect3DDevice9_BeginScene(device);
14080 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14081 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14082 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14084 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14085 hr = IDirect3DDevice9_EndScene(device);
14086 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14088 for (i = 0; i < 4; ++i)
14090 for (j = 0; j < 4; ++j)
14092 unsigned int x = 80 * ((2 * j) + 1);
14093 unsigned int y = 60 * ((2 * i) + 1);
14094 color = getPixelColor(device, x, y);
14095 ok(color_match(color, expected_colors[i][j], 0),
14096 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14100 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14101 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14103 IDirect3DSurface9_Release(ds3);
14104 IDirect3DSurface9_Release(ds2);
14105 IDirect3DSurface9_Release(ds1);
14106 refcount = IDirect3DDevice9_Release(device);
14107 ok(!refcount, "Device has %u references left.\n", refcount);
14108 done:
14109 IDirect3D9_Release(d3d);
14110 DestroyWindow(window);
14113 static void intz_test(void)
14115 static const DWORD ps_code[] =
14117 0xffff0200, /* ps_2_0 */
14118 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14119 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14120 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14121 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14122 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14123 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14124 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14125 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14126 0x0000ffff, /* end */
14128 struct
14130 float x, y, z;
14131 float s, t, p, q;
14133 quad[] =
14135 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14136 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14137 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14138 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14140 half_quad_1[] =
14142 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14143 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14144 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14145 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14147 half_quad_2[] =
14149 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14150 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14151 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14152 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14154 struct
14156 UINT x, y;
14157 D3DCOLOR color;
14159 expected_colors[] =
14161 { 80, 100, 0x20204020},
14162 {240, 100, 0x6060bf60},
14163 {400, 100, 0x9f9f409f},
14164 {560, 100, 0xdfdfbfdf},
14165 { 80, 450, 0x20204020},
14166 {240, 450, 0x6060bf60},
14167 {400, 450, 0x9f9f409f},
14168 {560, 450, 0xdfdfbfdf},
14171 IDirect3DSurface9 *original_rt, *rt;
14172 struct surface_readback rb;
14173 IDirect3DTexture9 *texture;
14174 IDirect3DPixelShader9 *ps;
14175 IDirect3DDevice9 *device;
14176 IDirect3DSurface9 *ds;
14177 IDirect3D9 *d3d;
14178 ULONG refcount;
14179 D3DCAPS9 caps;
14180 HWND window;
14181 HRESULT hr;
14182 UINT i;
14184 window = create_window();
14185 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14186 ok(!!d3d, "Failed to create a D3D object.\n");
14187 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14188 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14190 skip("No INTZ support, skipping INTZ test.\n");
14191 goto done;
14193 if (!(device = create_device(d3d, window, window, TRUE)))
14195 skip("Failed to create a D3D device, skipping tests.\n");
14196 goto done;
14199 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14200 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14201 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14203 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14204 IDirect3DDevice9_Release(device);
14205 goto done;
14207 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14209 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14210 IDirect3DDevice9_Release(device);
14211 goto done;
14214 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14215 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14217 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14218 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14219 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14220 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14221 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14222 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14223 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14224 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14226 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14227 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14228 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14229 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14231 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14232 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14233 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14238 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14239 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14240 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14241 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14242 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14243 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14244 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14246 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14248 /* Render offscreen, using the INTZ texture as depth buffer */
14249 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14250 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14251 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14252 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14253 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14254 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14255 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14256 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14258 /* Setup the depth/stencil surface. */
14259 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14260 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14262 hr = IDirect3DDevice9_BeginScene(device);
14263 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14265 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14266 hr = IDirect3DDevice9_EndScene(device);
14267 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14269 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14270 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14271 IDirect3DSurface9_Release(ds);
14272 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14273 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14275 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14276 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14277 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14279 /* Read the depth values back. */
14280 hr = IDirect3DDevice9_BeginScene(device);
14281 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14283 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14284 hr = IDirect3DDevice9_EndScene(device);
14285 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14287 get_rt_readback(original_rt, &rb);
14288 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14290 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14291 ok(color_match(color, expected_colors[i].color, 1),
14292 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14293 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14295 release_surface_readback(&rb);
14297 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14298 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14300 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14301 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14302 IDirect3DTexture9_Release(texture);
14304 /* Render onscreen while using the INTZ texture as depth buffer */
14305 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14306 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14307 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14308 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14309 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14310 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14311 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14312 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14314 /* Setup the depth/stencil surface. */
14315 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14316 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14318 hr = IDirect3DDevice9_BeginScene(device);
14319 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14321 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14322 hr = IDirect3DDevice9_EndScene(device);
14323 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14325 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14326 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14327 IDirect3DSurface9_Release(ds);
14328 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14329 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14330 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14331 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14333 /* Read the depth values back. */
14334 hr = IDirect3DDevice9_BeginScene(device);
14335 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14337 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14338 hr = IDirect3DDevice9_EndScene(device);
14339 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14341 get_rt_readback(original_rt, &rb);
14342 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14344 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14345 ok(color_match(color, expected_colors[i].color, 1),
14346 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14347 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14349 release_surface_readback(&rb);
14351 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14352 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14354 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14355 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14356 IDirect3DTexture9_Release(texture);
14358 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14359 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14360 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14361 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14362 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14364 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14365 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14366 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14367 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14368 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14369 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14371 /* Setup the depth/stencil surface. */
14372 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14373 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14375 hr = IDirect3DDevice9_BeginScene(device);
14376 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14378 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14379 hr = IDirect3DDevice9_EndScene(device);
14380 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14382 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14383 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14385 hr = IDirect3DDevice9_BeginScene(device);
14386 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14389 hr = IDirect3DDevice9_EndScene(device);
14390 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14392 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14393 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14394 IDirect3DSurface9_Release(ds);
14395 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14396 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14397 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14398 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14400 /* Read the depth values back. */
14401 hr = IDirect3DDevice9_BeginScene(device);
14402 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14405 hr = IDirect3DDevice9_EndScene(device);
14406 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14408 get_rt_readback(original_rt, &rb);
14409 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14411 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14412 ok(color_match(color, expected_colors[i].color, 1),
14413 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14414 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14416 release_surface_readback(&rb);
14418 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14419 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14421 IDirect3DTexture9_Release(texture);
14422 IDirect3DPixelShader9_Release(ps);
14423 IDirect3DSurface9_Release(original_rt);
14424 IDirect3DSurface9_Release(rt);
14425 refcount = IDirect3DDevice9_Release(device);
14426 ok(!refcount, "Device has %u references left.\n", refcount);
14427 done:
14428 IDirect3D9_Release(d3d);
14429 DestroyWindow(window);
14432 static void shadow_test(void)
14434 static const DWORD ps_code[] =
14436 0xffff0200, /* ps_2_0 */
14437 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14438 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14439 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14440 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14441 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14442 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14443 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14444 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14445 0x0000ffff, /* end */
14447 struct
14449 D3DFORMAT format;
14450 const char *name;
14452 formats[] =
14454 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14455 {D3DFMT_D32, "D3DFMT_D32"},
14456 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14457 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14458 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14459 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14460 {D3DFMT_D16, "D3DFMT_D16"},
14461 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14462 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14464 struct
14466 float x, y, z;
14467 float s, t, p, q;
14469 quad[] =
14471 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14472 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14473 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14474 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14476 struct
14478 UINT x, y;
14479 D3DCOLOR color;
14481 expected_colors[] =
14483 {400, 60, 0x00000000},
14484 {560, 180, 0xffff00ff},
14485 {560, 300, 0xffff00ff},
14486 {400, 420, 0xffffffff},
14487 {240, 420, 0xffffffff},
14488 { 80, 300, 0x00000000},
14489 { 80, 180, 0x00000000},
14490 {240, 60, 0x00000000},
14493 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14494 struct surface_readback rb;
14495 IDirect3DPixelShader9 *ps;
14496 IDirect3DDevice9 *device;
14497 IDirect3D9 *d3d;
14498 ULONG refcount;
14499 D3DCAPS9 caps;
14500 HWND window;
14501 HRESULT hr;
14502 UINT i;
14504 window = create_window();
14505 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14506 ok(!!d3d, "Failed to create a D3D object.\n");
14507 if (!(device = create_device(d3d, window, window, TRUE)))
14509 skip("Failed to create a D3D device, skipping tests.\n");
14510 goto done;
14513 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14514 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14515 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14517 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14518 IDirect3DDevice9_Release(device);
14519 goto done;
14522 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14523 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14524 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14525 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14527 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14528 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14529 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14530 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14531 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14533 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14534 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14536 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14538 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14539 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14540 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14542 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14544 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14545 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14546 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14547 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14548 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14549 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14550 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14551 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14552 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14553 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14555 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14557 D3DFORMAT format = formats[i].format;
14558 IDirect3DTexture9 *texture;
14559 IDirect3DSurface9 *ds;
14560 unsigned int j;
14562 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14563 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14564 continue;
14566 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14567 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14568 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14570 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14571 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14573 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14574 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14576 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14577 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14579 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14580 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14582 /* Setup the depth/stencil surface. */
14583 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14584 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14586 hr = IDirect3DDevice9_BeginScene(device);
14587 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14589 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14590 hr = IDirect3DDevice9_EndScene(device);
14591 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14593 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14594 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14595 IDirect3DSurface9_Release(ds);
14597 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14598 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14600 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14601 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14603 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14604 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14606 /* Do the actual shadow mapping. */
14607 hr = IDirect3DDevice9_BeginScene(device);
14608 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14610 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14611 hr = IDirect3DDevice9_EndScene(device);
14612 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14614 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14615 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14616 IDirect3DTexture9_Release(texture);
14618 get_rt_readback(original_rt, &rb);
14619 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14621 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14622 ok(color_match(color, expected_colors[j].color, 0),
14623 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14624 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14625 formats[i].name, color);
14627 release_surface_readback(&rb);
14629 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14630 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14633 IDirect3DPixelShader9_Release(ps);
14634 IDirect3DSurface9_Release(original_ds);
14635 IDirect3DSurface9_Release(original_rt);
14636 IDirect3DSurface9_Release(rt);
14637 refcount = IDirect3DDevice9_Release(device);
14638 ok(!refcount, "Device has %u references left.\n", refcount);
14639 done:
14640 IDirect3D9_Release(d3d);
14641 DestroyWindow(window);
14644 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14646 static const struct
14648 struct vec3 position;
14649 DWORD diffuse;
14651 quad1[] =
14653 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14654 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14655 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14656 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14658 quad2[] =
14660 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14661 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14662 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14663 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14665 D3DCOLOR color;
14666 HRESULT hr;
14668 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14669 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14671 hr = IDirect3DDevice9_BeginScene(device);
14672 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14674 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14675 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14677 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14678 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14680 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14682 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14683 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14685 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14687 hr = IDirect3DDevice9_EndScene(device);
14688 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14690 color = getPixelColor(device, 1, 240);
14691 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14692 color = getPixelColor(device, 638, 240);
14693 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14695 color = getPixelColor(device, 1, 241);
14696 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14697 color = getPixelColor(device, 638, 241);
14698 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14701 static void clip_planes_test(void)
14703 IDirect3DSurface9 *offscreen_surface, *original_rt;
14704 IDirect3DTexture9 *offscreen = NULL;
14705 IDirect3DVertexShader9 *shader;
14706 IDirect3DDevice9 *device;
14707 IDirect3D9 *d3d;
14708 ULONG refcount;
14709 D3DCAPS9 caps;
14710 HWND window;
14711 HRESULT hr;
14713 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14714 static const DWORD shader_code[] =
14716 0xfffe0200, /* vs_2_0 */
14717 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14718 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14719 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14720 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14721 0x0000ffff /* end */
14724 window = create_window();
14725 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14726 ok(!!d3d, "Failed to create a D3D object.\n");
14727 if (!(device = create_device(d3d, window, window, TRUE)))
14729 skip("Failed to create a D3D device, skipping tests.\n");
14730 goto done;
14733 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14734 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14735 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14737 skip("No vs_2_0 support, skipping tests.\n");
14738 IDirect3DDevice9_Release(device);
14739 goto done;
14742 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14743 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14746 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14748 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14749 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14750 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14752 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14754 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14755 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14756 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14757 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14759 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14761 clip_planes(device, "Onscreen FFP");
14763 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14764 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14765 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14766 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14767 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14768 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14770 clip_planes(device, "Offscreen FFP");
14772 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14773 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14775 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14776 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14777 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14778 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14780 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14781 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14783 clip_planes(device, "Onscreen vertex shader");
14785 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14786 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14788 clip_planes(device, "Offscreen vertex shader");
14790 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14791 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14793 IDirect3DVertexShader9_Release(shader);
14794 IDirect3DSurface9_Release(original_rt);
14795 IDirect3DSurface9_Release(offscreen_surface);
14796 IDirect3DTexture9_Release(offscreen);
14797 refcount = IDirect3DDevice9_Release(device);
14798 ok(!refcount, "Device has %u references left.\n", refcount);
14799 done:
14800 IDirect3D9_Release(d3d);
14801 DestroyWindow(window);
14804 static void fp_special_test(void)
14806 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14807 static const DWORD vs_header[] =
14809 0xfffe0200, /* vs_2_0 */
14810 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14811 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14812 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14813 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14816 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14817 static const DWORD vs_pow[] =
14818 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14819 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14820 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14821 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14822 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14823 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14824 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14825 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14826 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14827 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14828 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14830 static const DWORD vs_footer[] =
14832 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14833 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14834 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14835 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14836 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14837 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14838 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14839 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14840 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14841 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14842 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14843 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14844 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14845 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14846 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14847 0x0000ffff, /* end */
14850 static const struct
14852 const char *name;
14853 const DWORD *ops;
14854 DWORD size;
14855 D3DCOLOR r500;
14856 D3DCOLOR r600;
14857 D3DCOLOR nv40;
14858 D3DCOLOR nv50;
14859 D3DCOLOR warp;
14861 vs_body[] =
14863 /* The basic ideas here are:
14864 * 2.0 * +/-INF == +/-INF
14865 * NAN != NAN
14867 * The vertex shader value is written to the red component, with 0.0
14868 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14869 * result in 0x00. The pixel shader value is written to the green
14870 * component, but here 0.0 also results in 0x00. The actual value is
14871 * written to the blue component.
14873 * There are considerable differences between graphics cards in how
14874 * these are handled, but pow and nrm never generate INF or NAN on
14875 * real hardware. */
14876 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14877 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14878 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14879 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14880 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14881 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14882 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14883 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14884 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14885 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14886 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14889 static const DWORD ps_code[] =
14891 0xffff0200, /* ps_2_0 */
14892 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14893 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14894 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14895 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14896 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14897 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14898 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14899 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14900 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14901 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14902 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14903 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14904 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14905 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14906 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14907 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14908 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14909 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14910 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14911 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14912 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14913 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14914 0x0000ffff, /* end */
14917 struct
14919 float x, y, z;
14920 float s;
14922 quad[] =
14924 { -1.0f, 1.0f, 0.0f, 0.0f},
14925 { 1.0f, 1.0f, 1.0f, 0.0f},
14926 { -1.0f, -1.0f, 0.0f, 0.0f},
14927 { 1.0f, -1.0f, 1.0f, 0.0f},
14930 IDirect3DPixelShader9 *ps;
14931 IDirect3DDevice9 *device;
14932 UINT body_size = 0;
14933 IDirect3D9 *d3d;
14934 DWORD *vs_code;
14935 ULONG refcount;
14936 D3DCAPS9 caps;
14937 HWND window;
14938 HRESULT hr;
14939 UINT i;
14941 window = create_window();
14942 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14943 ok(!!d3d, "Failed to create a D3D object.\n");
14944 if (!(device = create_device(d3d, window, window, TRUE)))
14946 skip("Failed to create a D3D device, skipping tests.\n");
14947 goto done;
14950 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14951 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14952 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14954 skip("No shader model 2.0 support, skipping floating point specials test.\n");
14955 IDirect3DDevice9_Release(device);
14956 goto done;
14959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
14960 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14962 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14963 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14964 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14965 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14968 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
14971 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14973 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14975 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
14978 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
14979 memcpy(vs_code, vs_header, sizeof(vs_header));
14981 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14983 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
14984 IDirect3DVertexShader9 *vs;
14985 D3DCOLOR color;
14987 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
14988 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
14989 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
14991 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
14992 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
14993 hr = IDirect3DDevice9_SetVertexShader(device, vs);
14994 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14996 hr = IDirect3DDevice9_BeginScene(device);
14997 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14999 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15000 hr = IDirect3DDevice9_EndScene(device);
15001 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15003 color = getPixelColor(device, 320, 240);
15004 ok(color_match(color, vs_body[i].r500, 1)
15005 || color_match(color, vs_body[i].r600, 1)
15006 || color_match(color, vs_body[i].nv40, 1)
15007 || color_match(color, vs_body[i].nv50, 1)
15008 || broken(color_match(color, vs_body[i].warp, 1)),
15009 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15010 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15012 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15013 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15015 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15016 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15017 IDirect3DVertexShader9_Release(vs);
15020 HeapFree(GetProcessHeap(), 0, vs_code);
15022 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15023 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15024 IDirect3DPixelShader9_Release(ps);
15025 refcount = IDirect3DDevice9_Release(device);
15026 ok(!refcount, "Device has %u references left.\n", refcount);
15027 done:
15028 IDirect3D9_Release(d3d);
15029 DestroyWindow(window);
15032 static void srgbwrite_format_test(void)
15034 IDirect3D9 *d3d;
15035 IDirect3DSurface9 *rt, *backbuffer;
15036 IDirect3DTexture9 *texture;
15037 IDirect3DDevice9 *device;
15038 ULONG refcount;
15039 HWND window;
15040 HRESULT hr;
15041 int i;
15042 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15043 static const struct
15045 D3DFORMAT fmt;
15046 const char *name;
15048 formats[] =
15050 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15051 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15052 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15053 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15054 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15056 static const struct
15058 float x, y, z;
15059 float u, v;
15061 quad[] =
15063 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15064 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15065 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15066 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15069 window = create_window();
15070 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15071 ok(!!d3d, "Failed to create a D3D object.\n");
15072 if (!(device = create_device(d3d, window, window, TRUE)))
15074 skip("Failed to create a D3D device, skipping tests.\n");
15075 goto done;
15078 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15079 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15080 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15081 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15082 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15083 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15085 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15087 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15089 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15090 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15092 skip("Format %s not supported as render target, skipping test.\n",
15093 formats[i].name);
15094 continue;
15097 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15098 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15099 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15100 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15101 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15103 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15104 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15105 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15106 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15108 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15110 hr = IDirect3DDevice9_BeginScene(device);
15111 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15114 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15115 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15116 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15118 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15121 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15122 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15123 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15124 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15125 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15126 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15127 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15129 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15130 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15131 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15133 hr = IDirect3DDevice9_EndScene(device);
15134 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15136 IDirect3DSurface9_Release(rt);
15137 IDirect3DTexture9_Release(texture);
15139 color = getPixelColor(device, 360, 240);
15140 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15141 D3DUSAGE_QUERY_SRGBWRITE,
15142 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15144 /* Big slop for R5G6B5 */
15145 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15146 formats[i].name, color_srgb, color);
15148 else
15150 /* Big slop for R5G6B5 */
15151 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15152 formats[i].name, color_rgb, color);
15155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15156 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15159 IDirect3DSurface9_Release(backbuffer);
15160 refcount = IDirect3DDevice9_Release(device);
15161 ok(!refcount, "Device has %u references left.\n", refcount);
15162 done:
15163 IDirect3D9_Release(d3d);
15164 DestroyWindow(window);
15167 static void ds_size_test(void)
15169 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15170 IDirect3DDevice9 *device;
15171 DWORD num_passes;
15172 IDirect3D9 *d3d;
15173 ULONG refcount;
15174 HWND window;
15175 HRESULT hr;
15177 static const struct
15179 float x, y, z;
15181 quad[] =
15183 {-1.0f, -1.0f, 0.0f},
15184 {-1.0f, 1.0f, 0.0f},
15185 { 1.0f, -1.0f, 0.0f},
15186 { 1.0f, 1.0f, 0.0f},
15189 window = create_window();
15190 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15191 ok(!!d3d, "Failed to create a D3D object.\n");
15192 if (!(device = create_device(d3d, window, window, TRUE)))
15194 skip("Failed to create a D3D device, skipping tests.\n");
15195 goto done;
15198 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15199 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15200 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15201 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15202 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15203 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15205 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15206 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15209 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15211 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15213 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15214 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15215 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15216 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15217 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15218 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15219 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15220 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15221 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15222 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15223 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15224 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15225 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15227 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15228 * but does not change the surface's contents. */
15229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15230 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15232 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15234 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15236 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15238 /* Turning on any depth-related state results in a ValidateDevice failure */
15239 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15240 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15241 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15242 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15243 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15245 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15247 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15248 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15249 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15250 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15252 /* Try to draw with the device in an invalid state. */
15253 hr = IDirect3DDevice9_BeginScene(device);
15254 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15255 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15256 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15257 hr = IDirect3DDevice9_EndScene(device);
15258 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15260 /* Don't check the resulting draw unless we find an app that needs it. On
15261 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15262 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15263 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15265 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15266 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15267 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15268 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15269 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15270 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15272 IDirect3DSurface9_Release(readback);
15273 IDirect3DSurface9_Release(ds);
15274 IDirect3DSurface9_Release(rt);
15275 IDirect3DSurface9_Release(old_rt);
15276 IDirect3DSurface9_Release(old_ds);
15277 refcount = IDirect3DDevice9_Release(device);
15278 ok(!refcount, "Device has %u references left.\n", refcount);
15279 done:
15280 IDirect3D9_Release(d3d);
15281 DestroyWindow(window);
15284 static void unbound_sampler_test(void)
15286 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15287 IDirect3DSurface9 *rt, *old_rt;
15288 IDirect3DDevice9 *device;
15289 IDirect3D9 *d3d;
15290 ULONG refcount;
15291 D3DCAPS9 caps;
15292 DWORD color;
15293 HWND window;
15294 HRESULT hr;
15296 static const DWORD ps_code[] =
15298 0xffff0200, /* ps_2_0 */
15299 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15300 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15301 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15302 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15303 0x0000ffff, /* end */
15305 static const DWORD ps_code_cube[] =
15307 0xffff0200, /* ps_2_0 */
15308 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15309 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15310 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15311 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15312 0x0000ffff, /* end */
15314 static const DWORD ps_code_volume[] =
15316 0xffff0200, /* ps_2_0 */
15317 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15318 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15319 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15320 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15321 0x0000ffff, /* end */
15324 static const struct
15326 float x, y, z;
15327 float u, v;
15329 quad[] =
15331 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15332 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15333 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15334 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15337 window = create_window();
15338 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15339 ok(!!d3d, "Failed to create a D3D object.\n");
15340 if (!(device = create_device(d3d, window, window, TRUE)))
15342 skip("Failed to create a D3D device, skipping tests.\n");
15343 goto done;
15346 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15347 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15348 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15350 skip("No ps_2_0 support, skipping tests.\n");
15351 IDirect3DDevice9_Release(device);
15352 goto done;
15354 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15356 skip("No cube / volume texture support, skipping tests.\n");
15357 IDirect3DDevice9_Release(device);
15358 goto done;
15361 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15362 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15364 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15365 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15366 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15367 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15368 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15369 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15371 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15372 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15374 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15375 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15377 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15378 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15380 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15381 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15384 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15386 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15387 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15389 hr = IDirect3DDevice9_BeginScene(device);
15390 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15392 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15393 hr = IDirect3DDevice9_EndScene(device);
15394 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15396 color = getPixelColorFromSurface(rt, 32, 32);
15397 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15399 /* Now try with a cube texture */
15400 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15401 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15403 hr = IDirect3DDevice9_BeginScene(device);
15404 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15407 hr = IDirect3DDevice9_EndScene(device);
15408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15410 color = getPixelColorFromSurface(rt, 32, 32);
15411 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15413 /* And then with a volume texture */
15414 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15415 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15417 hr = IDirect3DDevice9_BeginScene(device);
15418 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15420 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15421 hr = IDirect3DDevice9_EndScene(device);
15422 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15424 color = getPixelColorFromSurface(rt, 32, 32);
15425 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15427 IDirect3DSurface9_Release(rt);
15428 IDirect3DSurface9_Release(old_rt);
15429 IDirect3DPixelShader9_Release(ps);
15430 IDirect3DPixelShader9_Release(ps_cube);
15431 IDirect3DPixelShader9_Release(ps_volume);
15432 refcount = IDirect3DDevice9_Release(device);
15433 ok(!refcount, "Device has %u references left.\n", refcount);
15434 done:
15435 IDirect3D9_Release(d3d);
15436 DestroyWindow(window);
15439 static void update_surface_test(void)
15441 static const BYTE blocks[][8] =
15443 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15444 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15445 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15446 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15447 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15448 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15449 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15451 static const struct
15453 UINT x, y;
15454 D3DCOLOR color;
15456 expected_colors[] =
15458 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15459 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15460 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15461 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15462 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15463 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15464 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15466 static const struct
15468 float x, y, z, w;
15469 float u, v;
15471 tri[] =
15473 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15474 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15475 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15477 static const RECT rect_2x2 = {0, 0, 2, 2};
15478 static const struct
15480 UINT src_level;
15481 UINT dst_level;
15482 const RECT *r;
15483 HRESULT hr;
15485 block_size_tests[] =
15487 {1, 0, NULL, D3D_OK},
15488 {0, 1, NULL, D3DERR_INVALIDCALL},
15489 {5, 4, NULL, D3DERR_INVALIDCALL},
15490 {4, 5, NULL, D3DERR_INVALIDCALL},
15491 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15492 {5, 5, &rect_2x2, D3D_OK},
15495 IDirect3DSurface9 *src_surface, *dst_surface;
15496 IDirect3DTexture9 *src_tex, *dst_tex;
15497 IDirect3DDevice9 *device;
15498 IDirect3D9 *d3d;
15499 ULONG refcount;
15500 UINT count, i;
15501 HWND window;
15502 HRESULT hr;
15504 window = create_window();
15505 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15506 ok(!!d3d, "Failed to create a D3D object.\n");
15507 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15508 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15510 skip("DXT1 not supported, skipping tests.\n");
15511 goto done;
15513 if (!(device = create_device(d3d, window, window, TRUE)))
15515 skip("Failed to create a D3D device, skipping tests.\n");
15516 goto done;
15519 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15520 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15521 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15522 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15524 count = IDirect3DTexture9_GetLevelCount(src_tex);
15525 ok(count == 7, "Got level count %u, expected 7.\n", count);
15527 for (i = 0; i < count; ++i)
15529 UINT row_count, block_count, x, y;
15530 D3DSURFACE_DESC desc;
15531 BYTE *row, *block;
15532 D3DLOCKED_RECT r;
15534 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15535 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15537 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15538 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15540 row_count = ((desc.Height + 3) & ~3) / 4;
15541 block_count = ((desc.Width + 3) & ~3) / 4;
15542 row = r.pBits;
15544 for (y = 0; y < row_count; ++y)
15546 block = row;
15547 for (x = 0; x < block_count; ++x)
15549 memcpy(block, blocks[i], sizeof(blocks[i]));
15550 block += sizeof(blocks[i]);
15552 row += r.Pitch;
15555 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15556 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15559 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15561 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15562 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15563 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15564 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15566 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15567 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15568 hr, i, block_size_tests[i].hr);
15570 IDirect3DSurface9_Release(dst_surface);
15571 IDirect3DSurface9_Release(src_surface);
15574 for (i = 0; i < count; ++i)
15576 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15577 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15578 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15579 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15581 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15582 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15584 IDirect3DSurface9_Release(dst_surface);
15585 IDirect3DSurface9_Release(src_surface);
15588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15589 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15590 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15591 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15592 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15593 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15594 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15595 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15596 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15597 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15598 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15599 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15601 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15602 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15604 hr = IDirect3DDevice9_BeginScene(device);
15605 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15608 hr = IDirect3DDevice9_EndScene(device);
15609 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15611 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15613 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15614 ok(color_match(color, expected_colors[i].color, 0),
15615 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15616 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15619 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15620 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15622 IDirect3DTexture9_Release(dst_tex);
15623 IDirect3DTexture9_Release(src_tex);
15624 refcount = IDirect3DDevice9_Release(device);
15625 ok(!refcount, "Device has %u references left.\n", refcount);
15626 done:
15627 IDirect3D9_Release(d3d);
15628 DestroyWindow(window);
15631 static void multisample_get_rtdata_test(void)
15633 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15634 IDirect3DDevice9 *device;
15635 IDirect3D9 *d3d;
15636 ULONG refcount;
15637 HWND window;
15638 HRESULT hr;
15640 window = create_window();
15641 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15642 ok(!!d3d, "Failed to create a D3D object.\n");
15643 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15644 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15646 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15647 goto done;
15649 if (!(device = create_device(d3d, window, window, TRUE)))
15651 skip("Failed to create a D3D device, skipping tests.\n");
15652 goto done;
15655 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15656 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15657 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15658 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15659 D3DPOOL_SYSTEMMEM, &readback, NULL);
15660 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15662 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15663 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15664 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15665 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15667 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15668 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15669 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15670 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15672 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15673 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15674 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15675 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15677 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15678 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15679 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15680 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15682 IDirect3DSurface9_Release(original_ds);
15683 IDirect3DSurface9_Release(original_rt);
15684 IDirect3DSurface9_Release(readback);
15685 IDirect3DSurface9_Release(rt);
15686 refcount = IDirect3DDevice9_Release(device);
15687 ok(!refcount, "Device has %u references left.\n", refcount);
15688 done:
15689 IDirect3D9_Release(d3d);
15690 DestroyWindow(window);
15693 static void multisampled_depth_buffer_test(void)
15695 IDirect3DDevice9 *device = 0;
15696 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15697 IDirect3D9 *d3d;
15698 D3DCAPS9 caps;
15699 HRESULT hr;
15700 D3DPRESENT_PARAMETERS present_parameters;
15701 unsigned int i;
15702 static const struct
15704 float x, y, z;
15705 D3DCOLOR color;
15707 quad_1[] =
15709 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15710 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15711 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15712 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15714 quad_2[] =
15716 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15717 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15718 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15719 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15721 static const struct
15723 UINT x, y;
15724 D3DCOLOR color;
15726 expected_colors[] =
15728 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15729 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15730 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15731 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15732 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15733 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15734 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15735 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15738 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15739 ok(!!d3d, "Failed to create a D3D object.\n");
15741 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15742 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15744 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15745 IDirect3D9_Release(d3d);
15746 return;
15748 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15749 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15751 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15752 IDirect3D9_Release(d3d);
15753 return;
15756 ZeroMemory(&present_parameters, sizeof(present_parameters));
15757 present_parameters.Windowed = TRUE;
15758 present_parameters.hDeviceWindow = create_window();
15759 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15760 present_parameters.BackBufferWidth = 640;
15761 present_parameters.BackBufferHeight = 480;
15762 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15763 present_parameters.EnableAutoDepthStencil = TRUE;
15764 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15765 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15767 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15768 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15769 &present_parameters, &device);
15770 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15772 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15773 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15774 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15776 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15777 goto cleanup;
15780 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15781 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15782 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15783 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15784 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15785 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15787 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15788 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15789 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15790 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15793 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15795 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15797 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15799 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15800 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15801 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15803 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15804 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15806 /* Render onscreen and then offscreen */
15807 hr = IDirect3DDevice9_BeginScene(device);
15808 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15810 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15811 hr = IDirect3DDevice9_EndScene(device);
15812 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15814 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15815 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15816 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15817 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15819 hr = IDirect3DDevice9_BeginScene(device);
15820 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15823 hr = IDirect3DDevice9_EndScene(device);
15824 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15826 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15827 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15829 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15831 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15832 ok(color_match(color, expected_colors[i].color, 1),
15833 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15834 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15837 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15838 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15839 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15840 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15842 /* Render offscreen and then onscreen */
15843 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15844 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15845 IDirect3DSurface9_Release(ds);
15846 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15847 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15848 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15849 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15850 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15853 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15855 hr = IDirect3DDevice9_BeginScene(device);
15856 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15857 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15858 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15859 hr = IDirect3DDevice9_EndScene(device);
15860 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15862 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15863 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15864 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15865 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15867 hr = IDirect3DDevice9_BeginScene(device);
15868 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15870 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15871 hr = IDirect3DDevice9_EndScene(device);
15872 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15874 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15875 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15877 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15879 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15880 ok(color_match(color, expected_colors[i].color, 1),
15881 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15882 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15885 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15886 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15888 IDirect3DSurface9_Release(ds);
15889 IDirect3DSurface9_Release(readback);
15890 IDirect3DSurface9_Release(rt);
15891 IDirect3DSurface9_Release(original_rt);
15892 cleanup_device(device);
15894 ZeroMemory(&present_parameters, sizeof(present_parameters));
15895 present_parameters.Windowed = TRUE;
15896 present_parameters.hDeviceWindow = create_window();
15897 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15898 present_parameters.BackBufferWidth = 640;
15899 present_parameters.BackBufferHeight = 480;
15900 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15901 present_parameters.EnableAutoDepthStencil = TRUE;
15902 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15903 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15905 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15906 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15907 &present_parameters, &device);
15908 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15911 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15913 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15914 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15915 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15916 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15917 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15918 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15919 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15920 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15921 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15923 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15924 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15925 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15926 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15927 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15928 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15929 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15930 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15933 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15935 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15937 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15939 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15941 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15943 /* Render to a multisampled offscreen frame buffer and then blit to
15944 * the onscreen (not multisampled) frame buffer. */
15945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15946 ok(SUCCEEDED(hr), "Failed to clear 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_1, sizeof(*quad_1));
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, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15956 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15957 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
15958 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15960 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15961 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15962 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15963 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15965 hr = IDirect3DDevice9_BeginScene(device);
15966 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15968 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15969 hr = IDirect3DDevice9_EndScene(device);
15970 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15972 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15973 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15975 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15977 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15978 ok(color_match(color, expected_colors[i].color, 1),
15979 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15980 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15983 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15984 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15986 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15987 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15988 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15989 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15991 IDirect3DSurface9_Release(original_ds);
15992 IDirect3DSurface9_Release(original_rt);
15993 IDirect3DSurface9_Release(ds);
15994 IDirect3DSurface9_Release(readback);
15995 IDirect3DSurface9_Release(rt);
15996 cleanup:
15997 cleanup_device(device);
15998 IDirect3D9_Release(d3d);
16001 static void resz_test(void)
16003 IDirect3DDevice9 *device = 0;
16004 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16005 D3DCAPS9 caps;
16006 HRESULT hr;
16007 D3DPRESENT_PARAMETERS present_parameters;
16008 unsigned int i;
16009 static const DWORD ps_code[] =
16011 0xffff0200, /* ps_2_0 */
16012 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16013 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16014 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16015 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16016 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16017 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16018 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16019 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16020 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16021 0x0000ffff, /* end */
16023 struct
16025 float x, y, z;
16026 float s, t, p, q;
16028 quad[] =
16030 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16031 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16032 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16033 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16035 struct
16037 UINT x, y;
16038 D3DCOLOR color;
16040 expected_colors[] =
16042 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16043 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16044 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16045 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16046 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16047 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16048 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16049 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16051 IDirect3DTexture9 *texture;
16052 IDirect3DPixelShader9 *ps;
16053 IDirect3D9 *d3d;
16054 DWORD value;
16056 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16057 ok(!!d3d, "Failed to create a D3D object.\n");
16059 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16060 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16062 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16063 IDirect3D9_Release(d3d);
16064 return;
16066 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16067 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16069 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16070 IDirect3D9_Release(d3d);
16071 return;
16074 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16075 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16077 skip("No INTZ support, skipping RESZ test.\n");
16078 IDirect3D9_Release(d3d);
16079 return;
16082 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16083 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16085 skip("No RESZ support, skipping RESZ test.\n");
16086 IDirect3D9_Release(d3d);
16087 return;
16090 ZeroMemory(&present_parameters, sizeof(present_parameters));
16091 present_parameters.Windowed = TRUE;
16092 present_parameters.hDeviceWindow = create_window();
16093 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16094 present_parameters.BackBufferWidth = 640;
16095 present_parameters.BackBufferHeight = 480;
16096 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16097 present_parameters.EnableAutoDepthStencil = FALSE;
16098 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16099 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16101 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16102 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16103 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16105 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16106 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16107 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16109 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16110 cleanup_device(device);
16111 IDirect3D9_Release(d3d);
16112 return;
16114 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16116 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16117 cleanup_device(device);
16118 IDirect3D9_Release(d3d);
16119 return;
16122 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16123 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16125 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16126 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16127 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16128 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16129 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16130 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16131 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16132 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16133 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16135 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16136 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16137 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16138 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16139 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16140 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16141 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16143 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16144 IDirect3DSurface9_Release(intz_ds);
16145 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16146 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16148 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16149 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16151 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16153 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16155 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16157 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16160 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16161 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16162 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16163 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16164 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16165 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16166 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16168 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16170 /* Render offscreen (multisampled), blit the depth buffer
16171 * into the INTZ texture and then check its contents */
16172 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16173 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16174 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16175 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16176 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16177 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16179 hr = IDirect3DDevice9_BeginScene(device);
16180 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16182 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16184 /* The destination depth texture has to be bound to sampler 0 */
16185 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16186 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16188 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16190 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16192 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16193 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16194 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16195 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16196 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16198 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16200 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16202 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16204 /* The actual multisampled depth buffer resolve happens here */
16205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16206 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16207 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16208 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16210 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16211 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16212 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16213 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16214 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16215 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16217 /* Read the depth values back */
16218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16219 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16220 hr = IDirect3DDevice9_EndScene(device);
16221 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16223 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16225 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16226 ok(color_match(color, expected_colors[i].color, 1),
16227 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16228 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16231 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16232 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16234 IDirect3DSurface9_Release(ds);
16235 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16236 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16237 IDirect3DTexture9_Release(texture);
16238 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16239 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16240 IDirect3DPixelShader9_Release(ps);
16241 IDirect3DSurface9_Release(readback);
16242 IDirect3DSurface9_Release(original_rt);
16243 IDirect3DSurface9_Release(rt);
16244 cleanup_device(device);
16246 ZeroMemory(&present_parameters, sizeof(present_parameters));
16247 present_parameters.Windowed = TRUE;
16248 present_parameters.hDeviceWindow = create_window();
16249 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16250 present_parameters.BackBufferWidth = 640;
16251 present_parameters.BackBufferHeight = 480;
16252 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16253 present_parameters.EnableAutoDepthStencil = TRUE;
16254 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16255 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16257 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16258 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16259 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16261 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16262 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16263 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16264 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16265 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16266 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16267 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16268 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16269 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16270 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16271 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16272 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16273 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16274 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16275 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16276 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16277 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16278 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16279 IDirect3DSurface9_Release(intz_ds);
16280 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16281 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16283 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16284 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16286 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16288 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16290 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16292 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16294 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16295 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16296 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16297 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16298 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16299 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16300 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16301 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16302 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16303 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16305 /* Render onscreen, blit the depth buffer into the INTZ texture
16306 * and then check its contents */
16307 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16308 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16309 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16310 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16312 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16314 hr = IDirect3DDevice9_BeginScene(device);
16315 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16317 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16318 hr = IDirect3DDevice9_EndScene(device);
16319 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16321 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16322 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16325 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16327 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16329 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16330 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16331 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16333 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16335 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16337 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16339 /* The actual multisampled depth buffer resolve happens here */
16340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16341 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16342 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16343 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16345 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16346 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16347 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16348 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16349 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16350 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16352 /* Read the depth values back */
16353 hr = IDirect3DDevice9_BeginScene(device);
16354 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16357 hr = IDirect3DDevice9_EndScene(device);
16358 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16360 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16362 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16363 ok(color_match(color, expected_colors[i].color, 1),
16364 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16365 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16369 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16372 /* Test edge cases - try with no texture at all */
16373 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16374 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16375 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16376 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16377 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16378 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16379 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16380 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16382 hr = IDirect3DDevice9_BeginScene(device);
16383 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16386 hr = IDirect3DDevice9_EndScene(device);
16387 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16390 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16392 /* With a non-multisampled depth buffer */
16393 IDirect3DSurface9_Release(ds);
16394 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16395 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16396 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16398 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16399 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16400 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16401 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16402 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16403 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16405 hr = IDirect3DDevice9_BeginScene(device);
16406 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16408 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16410 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16411 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16414 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16416 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16418 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16422 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16424 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16426 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16427 hr = IDirect3DDevice9_EndScene(device);
16428 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16431 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16433 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16434 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16436 /* Read the depth values back. */
16437 hr = IDirect3DDevice9_BeginScene(device);
16438 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16440 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16441 hr = IDirect3DDevice9_EndScene(device);
16442 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16444 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16446 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16447 ok(color_match(color, expected_colors[i].color, 1),
16448 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16449 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16452 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16453 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16455 /* Without a current depth-stencil buffer set */
16456 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16457 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16458 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16459 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16461 hr = IDirect3DDevice9_BeginScene(device);
16462 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16464 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16465 hr = IDirect3DDevice9_EndScene(device);
16466 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16469 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16471 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16472 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16473 IDirect3DSurface9_Release(ds);
16474 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16475 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16476 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16477 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16478 IDirect3DTexture9_Release(texture);
16479 IDirect3DPixelShader9_Release(ps);
16480 IDirect3DSurface9_Release(readback);
16481 IDirect3DSurface9_Release(original_rt);
16482 cleanup_device(device);
16483 IDirect3D9_Release(d3d);
16486 static void zenable_test(void)
16488 static const struct
16490 struct vec4 position;
16491 D3DCOLOR diffuse;
16493 tquad[] =
16495 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16496 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16497 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16498 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16500 IDirect3DDevice9 *device;
16501 IDirect3D9 *d3d;
16502 D3DCOLOR color;
16503 ULONG refcount;
16504 D3DCAPS9 caps;
16505 HWND window;
16506 HRESULT hr;
16507 UINT x, y;
16508 UINT i, j;
16509 UINT test;
16510 IDirect3DSurface9 *ds;
16512 window = create_window();
16513 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16514 ok(!!d3d, "Failed to create a D3D object.\n");
16515 if (!(device = create_device(d3d, window, window, TRUE)))
16517 skip("Failed to create a D3D device, skipping tests.\n");
16518 goto done;
16521 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16522 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16524 for (test = 0; test < 2; ++test)
16526 /* The Windows 8 testbot (WARP) appears to clip with
16527 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16528 static const D3DCOLOR expected_broken[] =
16530 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16531 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16532 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16533 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16536 if (!test)
16538 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16539 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16541 else
16543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16544 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16545 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16546 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16547 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16548 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16550 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16551 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16553 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16554 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16555 hr = IDirect3DDevice9_BeginScene(device);
16556 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16558 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16559 hr = IDirect3DDevice9_EndScene(device);
16560 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16562 for (i = 0; i < 4; ++i)
16564 for (j = 0; j < 4; ++j)
16566 x = 80 * ((2 * j) + 1);
16567 y = 60 * ((2 * i) + 1);
16568 color = getPixelColor(device, x, y);
16569 ok(color_match(color, 0x0000ff00, 1)
16570 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16571 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16572 x, y, color, test);
16576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16577 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16580 IDirect3DSurface9_Release(ds);
16582 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16583 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16585 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16586 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16588 static const DWORD vs_code[] =
16590 0xfffe0101, /* vs_1_1 */
16591 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16592 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16593 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16594 0x0000ffff
16596 static const DWORD ps_code[] =
16598 0xffff0101, /* ps_1_1 */
16599 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16600 0x0000ffff /* end */
16602 static const struct vec3 quad[] =
16604 {-1.0f, -1.0f, -0.5f},
16605 {-1.0f, 1.0f, -0.5f},
16606 { 1.0f, -1.0f, 1.5f},
16607 { 1.0f, 1.0f, 1.5f},
16609 static const D3DCOLOR expected[] =
16611 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16612 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16613 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16614 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16616 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16617 * vertices either. */
16618 static const D3DCOLOR expected_broken[] =
16620 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16621 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16622 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16623 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16626 IDirect3DVertexShader9 *vs;
16627 IDirect3DPixelShader9 *ps;
16629 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16630 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16631 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16632 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16633 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16634 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16635 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16636 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16637 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16638 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16640 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16641 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16642 hr = IDirect3DDevice9_BeginScene(device);
16643 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16645 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16646 hr = IDirect3DDevice9_EndScene(device);
16647 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16649 for (i = 0; i < 4; ++i)
16651 for (j = 0; j < 4; ++j)
16653 x = 80 * ((2 * j) + 1);
16654 y = 60 * ((2 * i) + 1);
16655 color = getPixelColor(device, x, y);
16656 ok(color_match(color, expected[i * 4 + j], 1)
16657 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16658 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16662 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16663 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16665 IDirect3DPixelShader9_Release(ps);
16666 IDirect3DVertexShader9_Release(vs);
16669 refcount = IDirect3DDevice9_Release(device);
16670 ok(!refcount, "Device has %u references left.\n", refcount);
16671 done:
16672 IDirect3D9_Release(d3d);
16673 DestroyWindow(window);
16676 static void fog_special_test(void)
16678 static const struct
16680 struct vec3 position;
16681 D3DCOLOR diffuse;
16683 quad[] =
16685 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16686 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16687 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16688 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16690 static const struct
16692 DWORD vertexmode, tablemode;
16693 BOOL vs, ps;
16694 D3DCOLOR color_left, color_right;
16696 tests[] =
16698 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16699 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16700 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16701 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16703 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16704 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16705 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16706 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16708 static const DWORD pixel_shader_code[] =
16710 0xffff0101, /* ps_1_1 */
16711 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16712 0x0000ffff
16714 static const DWORD vertex_shader_code[] =
16716 0xfffe0101, /* vs_1_1 */
16717 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16718 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16719 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16720 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16721 0x0000ffff
16723 static const D3DMATRIX identity =
16725 1.0f, 0.0f, 0.0f, 0.0f,
16726 0.0f, 1.0f, 0.0f, 0.0f,
16727 0.0f, 0.0f, 1.0f, 0.0f,
16728 0.0f, 0.0f, 0.0f, 1.0f,
16729 }}};
16730 union
16732 float f;
16733 DWORD d;
16734 } conv;
16735 DWORD color;
16736 HRESULT hr;
16737 unsigned int i;
16738 IDirect3DPixelShader9 *ps;
16739 IDirect3DVertexShader9 *vs;
16740 IDirect3DDevice9 *device;
16741 IDirect3D9 *d3d;
16742 ULONG refcount;
16743 D3DCAPS9 caps;
16744 HWND window;
16746 window = create_window();
16747 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16748 ok(!!d3d, "Failed to create a D3D object.\n");
16749 if (!(device = create_device(d3d, window, window, TRUE)))
16751 skip("Failed to create a D3D device, skipping tests.\n");
16752 goto done;
16755 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16756 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16757 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16759 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16760 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16762 else
16764 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16765 vs = NULL;
16767 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16769 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16770 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16772 else
16774 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16775 ps = NULL;
16778 /* The table fog tests seem to depend on the projection matrix explicitly
16779 * being set to an identity matrix, even though that's the default.
16780 * (AMD Radeon HD 6310, Windows 7) */
16781 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16782 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16785 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16787 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16789 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16791 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16793 conv.f = 0.5f;
16794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16795 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16797 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16799 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16801 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16802 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16804 if (!tests[i].vs)
16806 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16807 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16809 else if (vs)
16811 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16812 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16814 else
16816 continue;
16819 if (!tests[i].ps)
16821 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16822 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16824 else if (ps)
16826 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16827 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16829 else
16831 continue;
16834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16835 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16837 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16839 hr = IDirect3DDevice9_BeginScene(device);
16840 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16842 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16843 hr = IDirect3DDevice9_EndScene(device);
16844 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16846 color = getPixelColor(device, 310, 240);
16847 ok(color_match(color, tests[i].color_left, 1),
16848 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16849 color = getPixelColor(device, 330, 240);
16850 ok(color_match(color, tests[i].color_right, 1),
16851 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16854 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16857 if (vs)
16858 IDirect3DVertexShader9_Release(vs);
16859 if (ps)
16860 IDirect3DPixelShader9_Release(ps);
16861 refcount = IDirect3DDevice9_Release(device);
16862 ok(!refcount, "Device has %u references left.\n", refcount);
16863 done:
16864 IDirect3D9_Release(d3d);
16865 DestroyWindow(window);
16868 static void volume_srgb_test(void)
16870 HRESULT hr;
16871 unsigned int i, j;
16872 IDirect3DVolumeTexture9 *tex1, *tex2;
16873 D3DPOOL pool;
16874 D3DLOCKED_BOX locked_box;
16875 IDirect3DDevice9 *device;
16876 IDirect3D9 *d3d;
16877 D3DCOLOR color;
16878 ULONG refcount;
16879 HWND window;
16881 static const struct
16883 BOOL srgb;
16884 DWORD color;
16886 tests[] =
16888 /* Try toggling on and off */
16889 { FALSE, 0x007f7f7f },
16890 { TRUE, 0x00363636 },
16891 { FALSE, 0x007f7f7f },
16893 static const struct
16895 struct vec3 pos;
16896 struct vec3 texcrd;
16898 quad[] =
16900 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16901 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16902 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16903 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16906 window = create_window();
16907 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16908 ok(!!d3d, "Failed to create a D3D object.\n");
16909 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16910 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16912 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16913 goto done;
16915 if (!(device = create_device(d3d, window, window, TRUE)))
16917 skip("Failed to create a D3D device, skipping tests.\n");
16918 goto done;
16921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16922 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16924 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16925 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16926 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16927 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16928 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16930 for (i = 0; i < 2; i++)
16932 if (!i)
16933 pool = D3DPOOL_SYSTEMMEM;
16934 else
16935 pool = D3DPOOL_MANAGED;
16937 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
16938 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16939 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
16940 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16941 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
16942 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
16943 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16945 if (!i)
16947 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
16948 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
16949 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16950 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
16951 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16952 IDirect3DVolumeTexture9_Release(tex1);
16954 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
16955 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16956 IDirect3DVolumeTexture9_Release(tex2);
16958 else
16960 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
16961 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16962 IDirect3DVolumeTexture9_Release(tex1);
16965 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
16967 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
16968 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
16970 hr = IDirect3DDevice9_BeginScene(device);
16971 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16973 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16974 hr = IDirect3DDevice9_EndScene(device);
16975 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16977 color = getPixelColor(device, 320, 240);
16978 ok(color_match(color, tests[j].color, 2),
16979 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
16981 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16982 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16986 refcount = IDirect3DDevice9_Release(device);
16987 ok(!refcount, "Device has %u references left.\n", refcount);
16988 done:
16989 IDirect3D9_Release(d3d);
16990 DestroyWindow(window);
16993 static void volume_dxt5_test(void)
16995 IDirect3DVolumeTexture9 *texture;
16996 IDirect3DDevice9 *device;
16997 D3DLOCKED_BOX box;
16998 IDirect3D9 *d3d;
16999 unsigned int i;
17000 ULONG refcount;
17001 DWORD color;
17002 HWND window;
17003 HRESULT hr;
17005 static const char texture_data[] =
17007 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17008 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17009 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17010 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17011 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17013 static const struct
17015 struct vec3 position;
17016 struct vec3 texcrd;
17018 quads[] =
17020 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17021 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17022 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17023 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17025 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17026 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17027 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17028 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17030 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17032 window = create_window();
17033 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17034 ok(!!d3d, "Failed to create a D3D object.\n");
17035 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17036 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17038 skip("DXT5 volume textures are not supported, skipping test.\n");
17039 goto done;
17041 if (!(device = create_device(d3d, window, window, TRUE)))
17043 skip("Failed to create a D3D device, skipping tests.\n");
17044 goto done;
17047 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17048 D3DPOOL_MANAGED, &texture, NULL);
17049 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17051 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17052 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17053 memcpy(box.pBits, texture_data, sizeof(texture_data));
17054 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17055 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17058 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17059 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17060 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17061 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17062 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17063 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17064 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17065 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17066 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17067 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17068 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17070 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17071 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17072 hr = IDirect3DDevice9_BeginScene(device);
17073 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17075 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17076 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17077 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17078 hr = IDirect3DDevice9_EndScene(device);
17079 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17081 for (i = 0; i < 4; i++)
17083 color = getPixelColor(device, 80 + 160 * i, 240);
17084 ok (color_match(color, expected_colors[i], 1),
17085 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17088 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17089 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17090 IDirect3DVolumeTexture9_Release(texture);
17091 refcount = IDirect3DDevice9_Release(device);
17092 ok(!refcount, "Device has %u references left.\n", refcount);
17093 done:
17094 IDirect3D9_Release(d3d);
17095 DestroyWindow(window);
17098 static void volume_v16u16_test(void)
17100 IDirect3DVolumeTexture9 *texture;
17101 IDirect3DPixelShader9 *shader;
17102 IDirect3DDevice9 *device;
17103 D3DLOCKED_BOX box;
17104 IDirect3D9 *d3d;
17105 unsigned int i;
17106 ULONG refcount;
17107 D3DCAPS9 caps;
17108 SHORT *texel;
17109 DWORD color;
17110 HWND window;
17111 HRESULT hr;
17113 static const struct
17115 struct vec3 position;
17116 struct vec3 texcrd;
17118 quads[] =
17120 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17121 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17122 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17123 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17125 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17126 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17127 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17128 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17130 static const DWORD shader_code[] =
17132 0xffff0101, /* ps_1_1 */
17133 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17134 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17135 0x00000042, 0xb00f0000, /* tex t0 */
17136 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17137 0x0000ffff /* end */
17140 window = create_window();
17141 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17142 ok(!!d3d, "Failed to create a D3D object.\n");
17143 if (!(device = create_device(d3d, window, window, TRUE)))
17145 skip("Failed to create a D3D device, skipping tests.\n");
17146 goto done;
17149 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17150 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17151 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17153 skip("No ps_1_1 support, skipping tests.\n");
17154 IDirect3DDevice9_Release(device);
17155 goto done;
17157 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17158 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17160 skip("Volume V16U16 textures are not supported, skipping test.\n");
17161 IDirect3DDevice9_Release(device);
17162 goto done;
17165 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17166 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17167 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17168 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17169 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17170 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17171 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17172 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17174 for (i = 0; i < 2; i++)
17176 D3DPOOL pool;
17178 if (i)
17179 pool = D3DPOOL_SYSTEMMEM;
17180 else
17181 pool = D3DPOOL_MANAGED;
17183 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17184 pool, &texture, NULL);
17185 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17187 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17188 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17190 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17191 texel[0] = 32767;
17192 texel[1] = 32767;
17193 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17194 texel[0] = -32768;
17195 texel[1] = 0;
17196 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17197 texel[0] = -16384;
17198 texel[1] = 16384;
17199 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17200 texel[0] = 0;
17201 texel[1] = 0;
17203 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17204 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17206 if (i)
17208 IDirect3DVolumeTexture9 *texture2;
17210 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17211 D3DPOOL_DEFAULT, &texture2, NULL);
17212 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17214 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17215 (IDirect3DBaseTexture9 *)texture2);
17216 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17218 IDirect3DVolumeTexture9_Release(texture);
17219 texture = texture2;
17222 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17223 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17226 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17227 hr = IDirect3DDevice9_BeginScene(device);
17228 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17230 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17232 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17233 hr = IDirect3DDevice9_EndScene(device);
17234 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17236 color = getPixelColor(device, 120, 160);
17237 ok (color_match(color, 0x000080ff, 2),
17238 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17239 color = getPixelColor(device, 120, 400);
17240 ok (color_match(color, 0x00ffffff, 2),
17241 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17242 color = getPixelColor(device, 360, 160);
17243 ok (color_match(color, 0x007f7fff, 2),
17244 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17245 color = getPixelColor(device, 360, 400);
17246 ok (color_match(color, 0x0040c0ff, 2),
17247 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17249 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17250 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17252 IDirect3DVolumeTexture9_Release(texture);
17255 IDirect3DPixelShader9_Release(shader);
17256 refcount = IDirect3DDevice9_Release(device);
17257 ok(!refcount, "Device has %u references left.\n", refcount);
17258 done:
17259 IDirect3D9_Release(d3d);
17260 DestroyWindow(window);
17263 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17265 HRESULT hr;
17266 static const struct
17268 struct vec3 position;
17269 struct vec2 texcoord;
17271 quad[] =
17273 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17274 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17275 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17276 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17279 hr = IDirect3DDevice9_BeginScene(device);
17280 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17283 hr = IDirect3DDevice9_EndScene(device);
17284 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17287 static void add_dirty_rect_test(void)
17289 HRESULT hr;
17290 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
17291 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
17292 IDirect3DDevice9 *device;
17293 IDirect3D9 *d3d;
17294 unsigned int i;
17295 ULONG refcount;
17296 DWORD *texel;
17297 HWND window;
17298 D3DLOCKED_RECT locked_rect;
17299 static const RECT part_rect = {96, 96, 160, 160};
17300 DWORD color;
17302 window = create_window();
17303 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17304 ok(!!d3d, "Failed to create a D3D object.\n");
17305 if (!(device = create_device(d3d, window, window, TRUE)))
17307 skip("Failed to create a D3D device, skipping tests.\n");
17308 IDirect3D9_Release(d3d);
17309 DestroyWindow(window);
17310 return;
17313 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17314 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17315 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17316 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17317 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17318 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17319 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17320 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17321 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17322 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17323 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17324 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17325 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17326 D3DPOOL_MANAGED, &tex_managed, NULL);
17327 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17329 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17330 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17331 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17332 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17333 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17334 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17335 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17336 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17338 fill_surface(surface_src_red, 0x00ff0000, 0);
17339 fill_surface(surface_src_green, 0x0000ff00, 0);
17341 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17342 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17343 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17344 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17345 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17346 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17348 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17349 (IDirect3DBaseTexture9 *)tex_dst1);
17350 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17352 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17353 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17354 (IDirect3DBaseTexture9 *)tex_dst2);
17355 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17356 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17357 (IDirect3DBaseTexture9 *)tex_dst2);
17358 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17360 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17361 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17362 add_dirty_rect_test_draw(device);
17363 color = getPixelColor(device, 320, 240);
17364 ok(color_match(color, 0x0000ff00, 1),
17365 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17366 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17367 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17369 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17370 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17371 add_dirty_rect_test_draw(device);
17372 color = getPixelColor(device, 320, 240);
17373 todo_wine ok(color_match(color, 0x00ff0000, 1),
17374 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17376 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17378 /* AddDirtyRect on the destination is ignored. */
17379 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17380 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17381 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17382 (IDirect3DBaseTexture9 *)tex_dst2);
17383 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17384 add_dirty_rect_test_draw(device);
17385 color = getPixelColor(device, 320, 240);
17386 todo_wine ok(color_match(color, 0x00ff0000, 1),
17387 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17389 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17391 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17392 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17393 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17394 (IDirect3DBaseTexture9 *)tex_dst2);
17395 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17396 add_dirty_rect_test_draw(device);
17397 color = getPixelColor(device, 320, 240);
17398 todo_wine ok(color_match(color, 0x00ff0000, 1),
17399 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17400 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17401 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17403 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17404 * tracking is supported. */
17405 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17406 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17407 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17408 (IDirect3DBaseTexture9 *)tex_dst2);
17409 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17410 add_dirty_rect_test_draw(device);
17411 color = getPixelColor(device, 320, 240);
17412 ok(color_match(color, 0x0000ff00, 1),
17413 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17414 color = getPixelColor(device, 1, 1);
17415 todo_wine ok(color_match(color, 0x00ff0000, 1),
17416 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17417 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17418 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17420 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17421 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17422 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17423 (IDirect3DBaseTexture9 *)tex_dst2);
17424 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17425 add_dirty_rect_test_draw(device);
17426 color = getPixelColor(device, 1, 1);
17427 ok(color_match(color, 0x0000ff00, 1),
17428 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17430 /* Locks with NO_DIRTY_UPDATE are ignored. */
17431 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17432 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17433 (IDirect3DBaseTexture9 *)tex_dst2);
17434 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17435 add_dirty_rect_test_draw(device);
17436 color = getPixelColor(device, 320, 240);
17437 todo_wine ok(color_match(color, 0x0000ff00, 1),
17438 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17439 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17440 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17442 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17443 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17444 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17445 (IDirect3DBaseTexture9 *)tex_dst2);
17446 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17447 add_dirty_rect_test_draw(device);
17448 color = getPixelColor(device, 320, 240);
17449 todo_wine ok(color_match(color, 0x0000ff00, 1),
17450 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17451 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17452 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17454 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17455 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17456 (IDirect3DBaseTexture9 *)tex_dst2);
17457 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17458 add_dirty_rect_test_draw(device);
17459 color = getPixelColor(device, 320, 240);
17460 ok(color_match(color, 0x000000ff, 1),
17461 "Expected color 0x000000ff, got 0x%08x.\n", color);
17462 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17463 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17465 /* Maps without either of these flags record a dirty rectangle. */
17466 fill_surface(surface_src_green, 0x00ffffff, 0);
17467 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17468 (IDirect3DBaseTexture9 *)tex_dst2);
17469 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17470 add_dirty_rect_test_draw(device);
17471 color = getPixelColor(device, 320, 240);
17472 ok(color_match(color, 0x00ffffff, 1),
17473 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17474 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17475 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17477 /* Partial LockRect works just like a partial AddDirtyRect call. */
17478 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17479 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17480 texel = locked_rect.pBits;
17481 for (i = 0; i < 64; i++)
17482 texel[i] = 0x00ff00ff;
17483 for (i = 1; i < 64; i++)
17484 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17485 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17486 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17487 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17488 (IDirect3DBaseTexture9 *)tex_dst2);
17489 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17490 add_dirty_rect_test_draw(device);
17491 color = getPixelColor(device, 320, 240);
17492 ok(color_match(color, 0x00ff00ff, 1),
17493 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17494 color = getPixelColor(device, 1, 1);
17495 ok(color_match(color, 0x00ffffff, 1),
17496 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17497 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17498 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17500 fill_surface(surface_src_red, 0x00ff0000, 0);
17501 fill_surface(surface_src_green, 0x0000ff00, 0);
17503 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17504 (IDirect3DBaseTexture9 *)tex_dst1);
17505 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17506 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17507 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17508 add_dirty_rect_test_draw(device);
17509 color = getPixelColor(device, 320, 240);
17510 ok(color_match(color, 0x0000ff00, 1),
17511 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17512 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17513 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17515 /* UpdateSurface ignores the missing dirty marker. */
17516 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17517 (IDirect3DBaseTexture9 *)tex_dst2);
17518 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17519 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17520 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17521 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17522 add_dirty_rect_test_draw(device);
17523 color = getPixelColor(device, 320, 240);
17524 ok(color_match(color, 0x0000ff00, 1),
17525 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17526 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17527 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17529 fill_surface(surface_managed, 0x00ff0000, 0);
17530 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17531 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17532 add_dirty_rect_test_draw(device);
17533 color = getPixelColor(device, 320, 240);
17534 ok(color_match(color, 0x00ff0000, 1),
17535 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17536 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17537 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17539 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17540 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17541 add_dirty_rect_test_draw(device);
17542 color = getPixelColor(device, 320, 240);
17543 ok(color_match(color, 0x00ff0000, 1),
17544 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17545 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17546 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17548 /* AddDirtyRect uploads the new contents.
17549 * Side note, not tested in the test: Partial surface updates work, and two separate
17550 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17551 * untested. */
17552 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17553 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17554 add_dirty_rect_test_draw(device);
17555 color = getPixelColor(device, 320, 240);
17556 ok(color_match(color, 0x0000ff00, 1),
17557 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17558 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17559 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17561 /* So does EvictManagedResources. */
17562 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17563 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17564 hr = IDirect3DDevice9_EvictManagedResources(device);
17565 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17566 add_dirty_rect_test_draw(device);
17567 color = getPixelColor(device, 320, 240);
17568 ok(color_match(color, 0x000000ff, 1),
17569 "Expected color 0x000000ff, got 0x%08x.\n", color);
17570 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17571 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17573 /* AddDirtyRect on a locked texture is allowed. */
17574 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17575 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17576 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17577 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17578 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17579 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17581 /* Redundant AddDirtyRect calls are ok. */
17582 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17583 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17584 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17585 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17587 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17588 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17589 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17590 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17591 IDirect3DSurface9_Release(surface_dst2);
17592 IDirect3DSurface9_Release(surface_managed);
17593 IDirect3DSurface9_Release(surface_src_red);
17594 IDirect3DSurface9_Release(surface_src_green);
17595 IDirect3DTexture9_Release(tex_src_red);
17596 IDirect3DTexture9_Release(tex_src_green);
17597 IDirect3DTexture9_Release(tex_dst1);
17598 IDirect3DTexture9_Release(tex_dst2);
17599 IDirect3DTexture9_Release(tex_managed);
17600 refcount = IDirect3DDevice9_Release(device);
17601 ok(!refcount, "Device has %u references left.\n", refcount);
17602 IDirect3D9_Release(d3d);
17603 DestroyWindow(window);
17606 static void test_per_stage_constant(void)
17608 IDirect3DDevice9 *device;
17609 IDirect3D9 *d3d;
17610 D3DCOLOR color;
17611 ULONG refcount;
17612 D3DCAPS9 caps;
17613 HWND window;
17614 HRESULT hr;
17616 static const struct
17618 struct vec3 position;
17619 D3DCOLOR diffuse;
17621 quad[] =
17623 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17624 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17625 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17626 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17629 window = create_window();
17630 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17631 ok(!!d3d, "Failed to create a D3D object.\n");
17632 if (!(device = create_device(d3d, window, window, TRUE)))
17634 skip("Failed to create a D3D device, skipping tests.\n");
17635 goto done;
17638 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17639 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17640 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17642 skip("Per-stage constants not supported, skipping tests.\n");
17643 IDirect3DDevice9_Release(device);
17644 goto done;
17647 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17648 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17650 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17652 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17654 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17655 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17656 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17658 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17659 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17660 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17661 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17662 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17663 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17666 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17668 hr = IDirect3DDevice9_BeginScene(device);
17669 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17671 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17672 hr = IDirect3DDevice9_EndScene(device);
17673 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17675 color = getPixelColor(device, 320, 240);
17676 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17678 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17680 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17681 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17684 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17686 hr = IDirect3DDevice9_BeginScene(device);
17687 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17689 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17690 hr = IDirect3DDevice9_EndScene(device);
17691 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17693 color = getPixelColor(device, 320, 240);
17694 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17695 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17696 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17698 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17699 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17702 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17704 hr = IDirect3DDevice9_BeginScene(device);
17705 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17707 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17708 hr = IDirect3DDevice9_EndScene(device);
17709 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17711 color = getPixelColor(device, 320, 240);
17712 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17713 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17714 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17716 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17717 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17718 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17719 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17720 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17721 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17723 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17724 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17726 hr = IDirect3DDevice9_BeginScene(device);
17727 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17729 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17730 hr = IDirect3DDevice9_EndScene(device);
17731 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17733 color = getPixelColor(device, 320, 240);
17734 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17735 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17736 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17738 refcount = IDirect3DDevice9_Release(device);
17739 ok(!refcount, "Device has %u references left.\n", refcount);
17740 done:
17741 IDirect3D9_Release(d3d);
17742 DestroyWindow(window);
17745 static void test_3dc_formats(void)
17747 static const char ati1n_data[] =
17749 /* A 4x4 texture with the color component at 50%. */
17750 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17752 static const char ati2n_data[] =
17754 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17755 * 0% second component. Second block is the opposite. */
17756 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17759 static const struct
17761 struct vec3 position;
17762 struct vec2 texcoord;
17764 quads[] =
17766 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17767 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17768 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17769 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17771 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17772 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17773 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17774 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17776 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17777 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17778 static const struct
17780 struct vec2 position;
17781 D3DCOLOR amd_r500;
17782 D3DCOLOR amd_r600;
17783 D3DCOLOR nvidia_old;
17784 D3DCOLOR nvidia_new;
17786 expected_colors[] =
17788 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17789 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17790 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17791 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17793 IDirect3D9 *d3d;
17794 IDirect3DDevice9 *device;
17795 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17796 D3DCAPS9 caps;
17797 D3DLOCKED_RECT rect;
17798 D3DCOLOR color;
17799 ULONG refcount;
17800 HWND window;
17801 HRESULT hr;
17802 unsigned int i;
17804 window = create_window();
17805 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17806 ok(!!d3d, "Failed to create a D3D object.\n");
17807 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17808 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17810 skip("ATI1N textures are not supported, skipping test.\n");
17811 goto done;
17813 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17814 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17816 skip("ATI2N textures are not supported, skipping test.\n");
17817 goto done;
17819 if (!(device = create_device(d3d, window, window, TRUE)))
17821 skip("Failed to create a D3D device, skipping tests.\n");
17822 goto done;
17824 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17825 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17826 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17828 skip("D3DTA_TEMP not supported, skipping tests.\n");
17829 IDirect3DDevice9_Release(device);
17830 goto done;
17833 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17834 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17835 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17837 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17838 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17839 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17840 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17841 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17843 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17844 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17845 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17847 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17848 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17849 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17850 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17851 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17853 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17854 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17855 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17856 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17857 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17858 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17859 /* The temporary register is initialized to 0. */
17860 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17861 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17862 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17863 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17864 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17865 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17866 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17867 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17868 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17869 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17871 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17872 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17873 hr = IDirect3DDevice9_BeginScene(device);
17874 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17875 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17876 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17878 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17879 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17880 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17882 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17883 hr = IDirect3DDevice9_EndScene(device);
17884 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17886 for (i = 0; i < 4; ++i)
17888 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17889 ok (color_match(color, expected_colors[i].amd_r500, 1)
17890 || color_match(color, expected_colors[i].amd_r600, 1)
17891 || color_match(color, expected_colors[i].nvidia_old, 1)
17892 || color_match(color, expected_colors[i].nvidia_new, 1),
17893 "Got unexpected color 0x%08x, case %u.\n", color, i);
17896 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17897 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17898 IDirect3DTexture9_Release(ati2n_texture);
17899 IDirect3DTexture9_Release(ati1n_texture);
17900 refcount = IDirect3DDevice9_Release(device);
17901 ok(!refcount, "Device has %u references left.\n", refcount);
17903 done:
17904 IDirect3D9_Release(d3d);
17905 DestroyWindow(window);
17908 static void test_fog_interpolation(void)
17910 HRESULT hr;
17911 IDirect3DDevice9 *device;
17912 IDirect3D9 *d3d;
17913 ULONG refcount;
17914 HWND window;
17915 D3DCOLOR color;
17916 static const struct
17918 struct vec3 position;
17919 D3DCOLOR diffuse;
17920 D3DCOLOR specular;
17922 quad[] =
17924 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
17925 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
17926 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
17927 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
17929 union
17931 DWORD d;
17932 float f;
17933 } conv;
17934 unsigned int i;
17935 static const struct
17937 D3DFOGMODE vfog, tfog;
17938 D3DSHADEMODE shade;
17939 D3DCOLOR middle_color;
17940 BOOL todo;
17942 tests[] =
17944 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
17945 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
17946 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
17947 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
17948 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17949 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17950 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17951 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17953 static const D3DMATRIX ident_mat =
17955 1.0f, 0.0f, 0.0f, 0.0f,
17956 0.0f, 1.0f, 0.0f, 0.0f,
17957 0.0f, 0.0f, 1.0f, 0.0f,
17958 0.0f, 0.0f, 0.0f, 1.0f
17959 }}};
17960 D3DCAPS9 caps;
17962 window = create_window();
17963 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17964 ok(!!d3d, "Failed to create a D3D object.\n");
17966 if (!(device = create_device(d3d, window, window, TRUE)))
17968 skip("Failed to create a D3D device, skipping tests.\n");
17969 IDirect3D9_Release(d3d);
17970 DestroyWindow(window);
17971 return;
17974 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17975 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17976 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17977 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
17979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
17980 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17983 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
17984 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17986 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17988 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17989 conv.f = 5.0;
17990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
17991 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17994 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
17996 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
17998 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18000 /* Some of the tests seem to depend on the projection matrix explicitly
18001 * being set to an identity matrix, even though that's the default.
18002 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18003 * the drivers seem to use a static z = 1.0 input for the fog equation.
18004 * The input value is independent of the actual z and w component of
18005 * the vertex position. */
18006 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18007 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18009 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18011 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18012 continue;
18014 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18015 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18018 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18020 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18022 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18023 hr = IDirect3DDevice9_BeginScene(device);
18024 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18026 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18027 hr = IDirect3DDevice9_EndScene(device);
18028 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18030 color = getPixelColor(device, 0, 240);
18031 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18032 color = getPixelColor(device, 320, 240);
18033 todo_wine_if (tests[i].todo)
18034 ok(color_match(color, tests[i].middle_color, 2),
18035 "Got unexpected color 0x%08x, case %u.\n", color, i);
18036 color = getPixelColor(device, 639, 240);
18037 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18038 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18039 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18042 refcount = IDirect3DDevice9_Release(device);
18043 ok(!refcount, "Device has %u references left.\n", refcount);
18044 IDirect3D9_Release(d3d);
18045 DestroyWindow(window);
18048 static void test_negative_fixedfunction_fog(void)
18050 HRESULT hr;
18051 IDirect3DDevice9 *device;
18052 IDirect3D9 *d3d;
18053 ULONG refcount;
18054 HWND window;
18055 D3DCOLOR color;
18056 static const struct
18058 struct vec3 position;
18059 D3DCOLOR diffuse;
18061 quad[] =
18063 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18064 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18065 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18066 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18068 static const struct
18070 struct vec4 position;
18071 D3DCOLOR diffuse;
18073 tquad[] =
18075 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18076 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18077 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18078 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18080 unsigned int i;
18081 static const D3DMATRIX zero =
18083 1.0f, 0.0f, 0.0f, 0.0f,
18084 0.0f, 1.0f, 0.0f, 0.0f,
18085 0.0f, 0.0f, 0.0f, 0.0f,
18086 0.0f, 0.0f, 0.0f, 1.0f
18087 }}};
18088 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18089 * have an effect on RHW draws. */
18090 static const D3DMATRIX identity =
18092 1.0f, 0.0f, 0.0f, 0.0f,
18093 0.0f, 1.0f, 0.0f, 0.0f,
18094 0.0f, 0.0f, 1.0f, 0.0f,
18095 0.0f, 0.0f, 0.0f, 1.0f
18096 }}};
18097 static const struct
18099 DWORD pos_type;
18100 const void *quad;
18101 size_t stride;
18102 const D3DMATRIX *matrix;
18103 union
18105 float f;
18106 DWORD d;
18107 } start, end;
18108 D3DFOGMODE vfog, tfog;
18109 DWORD color, color_broken, color_broken2;
18111 tests[] =
18113 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18115 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18116 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18117 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18118 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18119 * parameters to 0.0 and 1.0 in the table fog case. */
18120 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18121 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18122 /* test_fog_interpolation shows that vertex fog evaluates the fog
18123 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18124 * that the abs happens before the fog equation is evaluated.
18126 * Vertex fog abs() behavior is the same on all GPUs. */
18127 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18128 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18129 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18130 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18131 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18132 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18134 D3DCAPS9 caps;
18136 window = create_window();
18137 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18138 ok(!!d3d, "Failed to create a D3D object.\n");
18140 if (!(device = create_device(d3d, window, window, TRUE)))
18142 skip("Failed to create a D3D device, skipping tests.\n");
18143 IDirect3D9_Release(d3d);
18144 DestroyWindow(window);
18145 return;
18148 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18149 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18150 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18151 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18154 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18155 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18156 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18158 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18159 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18160 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18162 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18164 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18166 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18167 continue;
18169 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18170 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18172 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18173 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18174 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18175 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18177 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18179 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18180 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18181 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18183 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18185 hr = IDirect3DDevice9_BeginScene(device);
18186 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18188 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18189 hr = IDirect3DDevice9_EndScene(device);
18190 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18192 color = getPixelColor(device, 320, 240);
18193 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18194 || broken(color_match(color, tests[i].color_broken2, 2)),
18195 "Got unexpected color 0x%08x, case %u.\n", color, i);
18196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18197 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18200 refcount = IDirect3DDevice9_Release(device);
18201 ok(!refcount, "Device has %u references left.\n", refcount);
18202 IDirect3D9_Release(d3d);
18203 DestroyWindow(window);
18206 static void test_position_index(void)
18208 static const D3DVERTEXELEMENT9 decl_elements[] =
18210 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18211 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18212 D3DDECL_END()
18214 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18215 * but works on Nvidia.
18216 * MSDN is not consistent on this point. */
18217 static const DWORD vs_code[] =
18219 0xfffe0300, /* vs_3_0 */
18220 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18221 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18222 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18223 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18224 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18225 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18226 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18227 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18228 0x0000ffff /* end */
18230 static const DWORD vs_code_2[] =
18232 0xfffe0300, /* vs_3_0 */
18233 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18234 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18235 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18236 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18237 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18238 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18239 0x0000ffff /* end */
18241 static const DWORD ps_code[] =
18243 0xffff0300, /* ps_3_0 */
18244 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18245 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18246 0x0000ffff /* end */
18248 static const DWORD ps_code_2[] =
18250 0xffff0300, /* ps_3_0 */
18251 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18252 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18253 0x0000ffff /* end */
18255 /* This one is considered invalid by the native shader assembler. */
18256 static const DWORD ps_code_bad[] =
18258 0xffff0300, /* ps_3_0 */
18259 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18260 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18261 0x0000ffff /* end */
18263 static const struct
18265 struct vec3 position;
18266 struct vec3 position1;
18268 quad[] =
18270 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18271 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18272 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18273 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18275 static const struct
18277 struct vec2 position;
18278 D3DCOLOR expected_color;
18279 D3DCOLOR broken_color;
18281 expected_colors[] =
18283 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18284 {{240, 240}, 0x009f6000, 0x00ff00ff},
18285 {{400, 240}, 0x00609f00, 0x00ff00ff},
18286 {{560, 240}, 0x0020df00, 0x00ff00ff},
18288 IDirect3D9 *d3d;
18289 IDirect3DDevice9 *device;
18290 IDirect3DVertexDeclaration9 *vertex_declaration;
18291 IDirect3DVertexShader9 *vs, *vs2;
18292 IDirect3DPixelShader9 *ps, *ps2;
18293 D3DCAPS9 caps;
18294 D3DCOLOR color;
18295 ULONG refcount;
18296 HWND window;
18297 HRESULT hr;
18298 unsigned int i;
18300 window = create_window();
18301 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18302 ok(!!d3d, "Failed to create a D3D object.\n");
18303 if (!(device = create_device(d3d, window, window, TRUE)))
18305 skip("Failed to create a D3D device, skipping tests.\n");
18306 goto done;
18309 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18310 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18311 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18312 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18314 skip("Shader model 3.0 unsupported, skipping tests.\n");
18315 IDirect3DDevice9_Release(device);
18316 goto done;
18319 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18320 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18322 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18323 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18325 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18326 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18327 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18328 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18330 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18331 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18333 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18334 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18336 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18337 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18338 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18339 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18341 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18342 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18344 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18345 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18346 hr = IDirect3DDevice9_BeginScene(device);
18347 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18349 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18350 hr = IDirect3DDevice9_EndScene(device);
18351 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18353 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18355 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18356 ok (color_match(color, expected_colors[i].expected_color, 1)
18357 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18358 "Got unexpected color 0x%08x, case %u.\n", color, i);
18361 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18362 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18365 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18366 hr = IDirect3DDevice9_BeginScene(device);
18367 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18369 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18370 hr = IDirect3DDevice9_EndScene(device);
18371 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18373 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18375 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18376 ok (color_match(color, expected_colors[i].expected_color, 1)
18377 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18378 "Got unexpected color 0x%08x, case %u.\n", color, i);
18381 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18382 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18384 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18385 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18386 hr = IDirect3DDevice9_BeginScene(device);
18387 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18389 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18390 hr = IDirect3DDevice9_EndScene(device);
18391 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18393 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18395 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18396 ok (color_match(color, expected_colors[i].expected_color, 1),
18397 "Got unexpected color 0x%08x, case %u.\n", color, i);
18400 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18401 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18403 IDirect3DPixelShader9_Release(ps2);
18404 IDirect3DPixelShader9_Release(ps);
18405 IDirect3DVertexShader9_Release(vs2);
18406 IDirect3DVertexShader9_Release(vs);
18407 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18408 refcount = IDirect3DDevice9_Release(device);
18409 ok(!refcount, "Device has %u references left.\n", refcount);
18411 done:
18412 IDirect3D9_Release(d3d);
18413 DestroyWindow(window);
18416 static void test_table_fog_zw(void)
18418 HRESULT hr;
18419 IDirect3DDevice9 *device;
18420 IDirect3D9 *d3d;
18421 ULONG refcount;
18422 HWND window;
18423 D3DCOLOR color;
18424 D3DCAPS9 caps;
18425 static struct
18427 struct vec4 position;
18428 D3DCOLOR diffuse;
18430 quad[] =
18432 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18433 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18434 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18435 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18437 static const D3DMATRIX identity =
18439 1.0f, 0.0f, 0.0f, 0.0f,
18440 0.0f, 1.0f, 0.0f, 0.0f,
18441 0.0f, 0.0f, 1.0f, 0.0f,
18442 0.0f, 0.0f, 0.0f, 1.0f
18443 }}};
18444 static const struct
18446 float z, w;
18447 D3DZBUFFERTYPE z_test;
18448 D3DCOLOR color;
18450 tests[] =
18452 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18453 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18454 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18455 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18456 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18457 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18458 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18459 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18461 unsigned int i;
18463 window = create_window();
18464 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18465 ok(!!d3d, "Failed to create a D3D object.\n");
18467 if (!(device = create_device(d3d, window, window, TRUE)))
18469 skip("Failed to create a D3D device, skipping tests.\n");
18470 IDirect3D9_Release(d3d);
18471 DestroyWindow(window);
18472 return;
18475 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18476 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18477 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18479 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18480 goto done;
18483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18484 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18486 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18488 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18490 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18491 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18492 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18493 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18495 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18496 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18497 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18499 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18501 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18502 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18504 quad[0].position.z = tests[i].z;
18505 quad[1].position.z = tests[i].z;
18506 quad[2].position.z = tests[i].z;
18507 quad[3].position.z = tests[i].z;
18508 quad[0].position.w = tests[i].w;
18509 quad[1].position.w = tests[i].w;
18510 quad[2].position.w = tests[i].w;
18511 quad[3].position.w = tests[i].w;
18512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18513 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18515 hr = IDirect3DDevice9_BeginScene(device);
18516 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18518 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18519 hr = IDirect3DDevice9_EndScene(device);
18520 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18522 color = getPixelColor(device, 320, 240);
18523 ok(color_match(color, tests[i].color, 2),
18524 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18525 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18526 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18529 done:
18530 refcount = IDirect3DDevice9_Release(device);
18531 ok(!refcount, "Device has %u references left.\n", refcount);
18532 IDirect3D9_Release(d3d);
18533 DestroyWindow(window);
18536 static void test_signed_formats(void)
18538 IDirect3DDevice9 *device;
18539 HWND window;
18540 HRESULT hr;
18541 unsigned int i, j, x, y;
18542 IDirect3DTexture9 *texture, *texture_sysmem;
18543 IDirect3DSurface9 *src_surface, *dst_surface;
18544 D3DLOCKED_RECT locked_rect;
18545 IDirect3DPixelShader9 *shader, *shader_alpha;
18546 IDirect3D9 *d3d;
18547 D3DCOLOR color;
18548 D3DCAPS9 caps;
18549 ULONG refcount;
18551 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18552 * to the other formats because L6V5U5 is the lowest precision format.
18553 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18554 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18555 * Some other intermediate values are tested too. The input value -15
18556 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18557 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18558 * using the expected output data the 8 bit and 16 bit values in V8U8
18559 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18560 * -1, 1 and -127 are not tested in V8U8.
18562 * 8 bit specific values like -127 are tested in the Q channel of
18563 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18564 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18565 * -128. The difference between using -127 or -128 as the lowest
18566 * possible value gets lost in the slop of 1 though. */
18567 static const USHORT content_v8u8[4][4] =
18569 {0x0000, 0x7f7f, 0x8880, 0x0000},
18570 {0x0080, 0x8000, 0x7f00, 0x007f},
18571 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18572 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18574 static const DWORD content_v16u16[4][4] =
18576 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18577 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18578 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18579 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18581 static const DWORD content_q8w8v8u8[4][4] =
18583 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18584 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18585 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18586 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18588 static const DWORD content_x8l8v8u8[4][4] =
18590 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18591 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18592 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18593 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18595 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18596 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18597 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18598 * though.
18600 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18601 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18602 * the proper results of -6 and -2.
18604 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18605 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18606 * is 0x84 instead of 0x80. */
18607 static const USHORT content_l6v5u5[4][4] =
18609 {0x0000, 0xfdef, 0x0230, 0xfc00},
18610 {0x0010, 0x0200, 0x01e0, 0x000f},
18611 {0x4067, 0x53b9, 0x0421, 0xffff},
18612 {0x8108, 0x0318, 0xc28c, 0x909c},
18614 static const struct
18616 D3DFORMAT format;
18617 const char *name;
18618 const void *content;
18619 SIZE_T pixel_size;
18620 BOOL blue, alpha;
18621 unsigned int slop, slop_broken, alpha_broken;
18623 formats[] =
18625 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18626 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18627 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18628 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18629 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18631 static const struct
18633 D3DPOOL pool;
18634 UINT width;
18635 RECT src_rect;
18636 POINT dst_point;
18638 tests[] =
18640 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18641 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18642 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18643 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18645 static const DWORD shader_code[] =
18647 0xffff0101, /* ps_1_1 */
18648 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18649 0x00000042, 0xb00f0000, /* tex t0 */
18650 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18651 0x0000ffff /* end */
18653 static const DWORD shader_code_alpha[] =
18655 /* The idea of this shader is to replicate the alpha value in .rg, and set
18656 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18657 0xffff0101, /* ps_1_1 */
18658 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18659 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18660 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18661 0x00000042, 0xb00f0000, /* tex t0 */
18662 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18663 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18664 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18665 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18666 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18667 0x0000ffff /* end */
18669 static const struct
18671 struct vec3 position;
18672 struct vec2 texcrd;
18674 quad[] =
18676 /* Flip the y coordinate to make the input and
18677 * output arrays easier to compare. */
18678 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18679 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18680 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18681 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18683 static const D3DCOLOR expected_alpha[4][4] =
18685 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18686 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18687 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18688 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18690 static const BOOL alpha_broken[4][4] =
18692 {FALSE, FALSE, FALSE, FALSE},
18693 {FALSE, FALSE, FALSE, FALSE},
18694 {FALSE, FALSE, FALSE, TRUE },
18695 {FALSE, FALSE, FALSE, FALSE},
18697 static const D3DCOLOR expected_colors[4][4] =
18699 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18700 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18701 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18702 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18704 static const D3DCOLOR expected_colors2[4][4] =
18706 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18707 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18708 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18709 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18711 static const D3DCOLOR expected_colors3[4] =
18713 0x00018080,
18714 0x00ba98a0,
18715 0x00ba98a0,
18716 0x00c3c3c0,
18718 D3DCOLOR expected_color;
18720 window = create_window();
18721 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18722 ok(!!d3d, "Failed to create a D3D object.\n");
18724 if (!(device = create_device(d3d, window, window, TRUE)))
18726 skip("Failed to create a D3D device, skipping tests.\n");
18727 IDirect3D9_Release(d3d);
18728 DestroyWindow(window);
18729 return;
18732 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18733 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18735 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18737 skip("Pixel shaders not supported, skipping converted format test.\n");
18738 goto done;
18741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18742 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18743 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18744 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18745 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18746 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18747 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18748 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18750 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18752 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18753 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18754 if (FAILED(hr))
18756 skip("Format %s not supported, skipping.\n", formats[i].name);
18757 continue;
18760 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18762 texture_sysmem = NULL;
18763 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18764 formats[i].format, tests[j].pool, &texture, NULL);
18765 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18767 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18768 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18769 for (y = 0; y < 4; y++)
18771 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18772 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18773 tests[j].width * formats[i].pixel_size);
18775 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18776 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18778 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18780 texture_sysmem = texture;
18781 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18782 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18783 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18785 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18786 (IDirect3DBaseTexture9 *)texture);
18787 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18790 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18791 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18792 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18793 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18796 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18797 hr = IDirect3DDevice9_BeginScene(device);
18798 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18800 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18801 hr = IDirect3DDevice9_EndScene(device);
18802 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18804 for (y = 0; y < 4; y++)
18806 for (x = 0; x < tests[j].width; x++)
18808 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18809 if (formats[i].alpha)
18810 expected_color = expected_alpha[y][x];
18811 else
18812 expected_color = 0x00ffff00;
18814 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18815 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18816 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18817 expected_color, color, formats[i].name, x, y);
18820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18821 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18823 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18824 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18827 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18828 hr = IDirect3DDevice9_BeginScene(device);
18829 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18831 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18832 hr = IDirect3DDevice9_EndScene(device);
18833 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18835 for (y = 0; y < 4; y++)
18837 for (x = 0; x < tests[j].width; x++)
18839 expected_color = expected_colors[y][x];
18840 if (!formats[i].blue)
18841 expected_color |= 0x000000ff;
18843 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18844 ok(color_match(color, expected_color, formats[i].slop)
18845 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18846 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18847 expected_color, color, formats[i].name, x, y);
18850 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18851 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18853 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18855 IDirect3DTexture9_Release(texture);
18856 continue;
18859 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18860 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18861 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18862 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18864 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18865 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18866 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18868 IDirect3DSurface9_Release(dst_surface);
18869 IDirect3DSurface9_Release(src_surface);
18871 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18872 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18873 hr = IDirect3DDevice9_BeginScene(device);
18874 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18876 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18877 hr = IDirect3DDevice9_EndScene(device);
18878 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18880 for (y = 0; y < 4; y++)
18882 for (x = 0; x < tests[j].width; x++)
18884 if (tests[j].width == 4)
18885 expected_color = expected_colors2[y][x];
18886 else
18887 expected_color = expected_colors3[y];
18889 if (!formats[i].blue)
18890 expected_color |= 0x000000ff;
18892 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18893 ok(color_match(color, expected_color, formats[i].slop)
18894 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18895 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18896 expected_color, color, formats[i].name, x, y);
18899 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18900 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18902 IDirect3DTexture9_Release(texture_sysmem);
18903 IDirect3DTexture9_Release(texture);
18907 IDirect3DPixelShader9_Release(shader);
18908 IDirect3DPixelShader9_Release(shader_alpha);
18910 done:
18911 refcount = IDirect3DDevice9_Release(device);
18912 ok(!refcount, "Device has %u references left.\n", refcount);
18913 IDirect3D9_Release(d3d);
18914 DestroyWindow(window);
18917 static void test_multisample_mismatch(void)
18919 IDirect3DDevice9 *device;
18920 IDirect3D9 *d3d;
18921 HWND window;
18922 HRESULT hr;
18923 D3DCOLOR color;
18924 ULONG refcount;
18925 IDirect3DSurface9 *rt, *rt_multi, *ds;
18926 static const struct
18928 struct vec3 position;
18929 DWORD color;
18931 quad[] =
18933 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
18934 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
18935 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
18936 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
18939 window = create_window();
18940 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18941 ok(!!d3d, "Failed to create a D3D object.\n");
18942 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18943 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18945 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
18946 IDirect3D9_Release(d3d);
18947 return;
18949 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18950 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18952 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
18953 IDirect3D9_Release(d3d);
18954 return;
18957 if (!(device = create_device(d3d, window, window, TRUE)))
18959 skip("Failed to create a D3D device, skipping tests.\n");
18960 IDirect3D9_Release(d3d);
18961 DestroyWindow(window);
18962 return;
18965 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18966 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
18967 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
18969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
18970 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18972 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18973 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
18974 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
18975 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
18976 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18977 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18980 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18984 /* Clear with incompatible buffers. Partial and combined clears. */
18985 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18986 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18987 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
18988 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
18990 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18992 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
18993 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18994 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18995 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18996 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18997 color = getPixelColor(device, 320, 240);
18998 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18999 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19000 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19002 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19003 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19004 * the Z only clear case nor in the combined clear case. */
19005 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19006 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19007 hr = IDirect3DDevice9_BeginScene(device);
19008 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19009 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19010 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19011 hr = IDirect3DDevice9_EndScene(device);
19012 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19013 color = getPixelColor(device, 62, 240);
19014 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19015 color = getPixelColor(device, 64, 240);
19016 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19017 "Got unexpected color 0x%08x.\n", color);
19018 color = getPixelColor(device, 318, 240);
19019 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19020 "Got unexpected color 0x%08x.\n", color);
19021 color = getPixelColor(device, 322, 240);
19022 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19023 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19024 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19026 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19027 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19028 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19029 * show up either. Only test the ZENABLE = FALSE case for now. */
19030 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19031 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19032 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19033 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19035 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19036 hr = IDirect3DDevice9_BeginScene(device);
19037 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19039 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19040 hr = IDirect3DDevice9_EndScene(device);
19041 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19043 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19044 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19045 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19046 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19047 color = getPixelColor(device, 320, 240);
19048 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19049 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19050 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19052 IDirect3DSurface9_Release(ds);
19054 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19055 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19056 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19057 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19058 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19059 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19060 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19061 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19062 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19063 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19064 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19066 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19067 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19069 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19070 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19071 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19073 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19075 color = getPixelColor(device, 320, 240);
19076 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19077 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19078 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19080 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19081 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19083 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19084 hr = IDirect3DDevice9_BeginScene(device);
19085 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19087 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19088 hr = IDirect3DDevice9_EndScene(device);
19089 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19091 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19092 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19093 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19094 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19095 color = getPixelColor(device, 62, 240);
19096 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19097 color = getPixelColor(device, 318, 240);
19098 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19099 "Got unexpected color 0x%08x.\n", color);
19100 color = getPixelColor(device, 322, 240);
19101 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19102 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19103 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19105 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19106 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19107 * is disabled. Again only test the ZENABLE = FALSE case. */
19108 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19109 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19111 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19112 hr = IDirect3DDevice9_BeginScene(device);
19113 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19114 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19115 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19116 hr = IDirect3DDevice9_EndScene(device);
19117 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19118 color = getPixelColor(device, 320, 240);
19119 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19120 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19121 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19123 IDirect3DSurface9_Release(rt);
19124 IDirect3DSurface9_Release(ds);
19125 IDirect3DSurface9_Release(rt_multi);
19127 refcount = IDirect3DDevice9_Release(device);
19128 ok(!refcount, "Device has %u references left.\n", refcount);
19129 IDirect3D9_Release(d3d);
19130 DestroyWindow(window);
19133 static void test_texcoordindex(void)
19135 static const D3DMATRIX mat =
19137 1.0f, 0.0f, 0.0f, 0.0f,
19138 0.0f, 0.0f, 0.0f, 0.0f,
19139 0.0f, 0.0f, 0.0f, 0.0f,
19140 0.0f, 0.0f, 0.0f, 0.0f,
19141 }}};
19142 static const struct
19144 struct vec3 pos;
19145 struct vec2 texcoord1;
19146 struct vec2 texcoord2;
19147 struct vec2 texcoord3;
19149 quad[] =
19151 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19152 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19153 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19154 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19156 IDirect3DDevice9 *device;
19157 IDirect3D9 *d3d9;
19158 HWND window;
19159 HRESULT hr;
19160 IDirect3DTexture9 *texture1, *texture2;
19161 D3DLOCKED_RECT locked_rect;
19162 ULONG refcount;
19163 D3DCOLOR color;
19164 DWORD *ptr;
19166 window = create_window();
19167 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19168 ok(!!d3d9, "Failed to create a D3D object.\n");
19169 if (!(device = create_device(d3d9, window, window, TRUE)))
19171 skip("Failed to create a D3D device, skipping tests.\n");
19172 IDirect3D9_Release(d3d9);
19173 DestroyWindow(window);
19174 return;
19177 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19178 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19179 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19180 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19182 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19183 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19184 ptr = locked_rect.pBits;
19185 ptr[0] = 0xff000000;
19186 ptr[1] = 0xff00ff00;
19187 ptr[2] = 0xff0000ff;
19188 ptr[3] = 0xff00ffff;
19189 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19190 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19192 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19193 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19194 ptr = locked_rect.pBits;
19195 ptr[0] = 0xff000000;
19196 ptr[1] = 0xff0000ff;
19197 ptr[2] = 0xffff0000;
19198 ptr[3] = 0xffff00ff;
19199 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19200 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19202 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19203 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19204 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19205 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19207 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19209 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19210 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19211 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19212 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19213 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19214 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19215 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19216 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19217 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19218 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19219 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19220 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19221 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19223 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19224 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19225 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19226 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19228 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19229 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19231 hr = IDirect3DDevice9_BeginScene(device);
19232 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19234 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19235 hr = IDirect3DDevice9_EndScene(device);
19236 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19238 color = getPixelColor(device, 160, 120);
19239 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19240 color = getPixelColor(device, 480, 120);
19241 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19242 color = getPixelColor(device, 160, 360);
19243 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19244 color = getPixelColor(device, 480, 360);
19245 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19247 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19248 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19249 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19250 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19253 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19255 hr = IDirect3DDevice9_BeginScene(device);
19256 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19258 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19259 hr = IDirect3DDevice9_EndScene(device);
19260 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19262 color = getPixelColor(device, 160, 120);
19263 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19264 color = getPixelColor(device, 480, 120);
19265 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19266 color = getPixelColor(device, 160, 360);
19267 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19268 color = getPixelColor(device, 480, 360);
19269 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19271 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19272 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19273 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19274 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19277 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19279 hr = IDirect3DDevice9_BeginScene(device);
19280 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19283 hr = IDirect3DDevice9_EndScene(device);
19284 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19286 color = getPixelColor(device, 160, 120);
19287 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19288 color = getPixelColor(device, 480, 120);
19289 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19290 color = getPixelColor(device, 160, 360);
19291 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19292 color = getPixelColor(device, 480, 360);
19293 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19295 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19296 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19298 IDirect3DTexture9_Release(texture1);
19299 IDirect3DTexture9_Release(texture2);
19301 refcount = IDirect3DDevice9_Release(device);
19302 ok(!refcount, "Device has %u references left.\n", refcount);
19303 IDirect3D9_Release(d3d9);
19304 DestroyWindow(window);
19307 static void test_vertex_blending(void)
19309 IDirect3DVertexDeclaration9 *vertex_declaration;
19310 IDirect3DDevice9 *device;
19311 IDirect3D9 *d3d;
19312 D3DCAPS9 caps;
19313 D3DCOLOR color;
19314 ULONG refcount;
19315 HWND window;
19316 HRESULT hr;
19317 int i;
19319 static const D3DMATRIX view_mat =
19321 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19322 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19323 0.0f, 0.0f, 1.0f, 0.0f,
19324 0.0f, 0.0f, 0.0f, 1.0f
19325 }}},
19326 upper_left =
19328 1.0f, 0.0f, 0.0f, 0.0f,
19329 0.0f, 1.0f, 0.0f, 0.0f,
19330 0.0f, 0.0f, 1.0f, 0.0f,
19331 -4.0f, 4.0f, 0.0f, 1.0f
19332 }}},
19333 lower_left =
19335 1.0f, 0.0f, 0.0f, 0.0f,
19336 0.0f, 1.0f, 0.0f, 0.0f,
19337 0.0f, 0.0f, 1.0f, 0.0f,
19338 -4.0f, -4.0f, 0.0f, 1.0f
19339 }}},
19340 upper_right =
19342 1.0f, 0.0f, 0.0f, 0.0f,
19343 0.0f, 1.0f, 0.0f, 0.0f,
19344 0.0f, 0.0f, 1.0f, 0.0f,
19345 4.0f, 4.0f, 0.0f, 1.0f
19346 }}},
19347 lower_right =
19349 1.0f, 0.0f, 0.0f, 0.0f,
19350 0.0f, 1.0f, 0.0f, 0.0f,
19351 0.0f, 0.0f, 1.0f, 0.0f,
19352 4.0f, -4.0f, 0.0f, 1.0f
19353 }}};
19355 static const POINT quad_upper_right_points[] =
19357 {576, 48}, {-1, -1},
19359 quad_upper_right_empty_points[] =
19361 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19363 quad_center_points[] =
19365 {320, 240}, {-1, -1}
19367 quad_center_empty_points[] =
19369 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19371 quad_upper_center_points[] =
19373 {320, 48}, {-1, -1}
19375 quad_upper_center_empty_points[] =
19377 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19379 quad_fullscreen_points[] =
19381 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19383 quad_fullscreen_empty_points[] =
19385 {-1, -1}
19388 static const struct
19390 DWORD fvf;
19391 D3DVERTEXELEMENT9 decl_elements[3];
19392 struct
19394 struct
19396 struct vec3 position;
19397 struct vec3 blendweights;
19399 vertex_data_float[4];
19400 struct
19402 struct vec3 position;
19403 D3DCOLOR blendweights;
19405 vertex_data_d3dcolor[4];
19406 } s;
19407 const POINT *quad_points;
19408 const POINT *empty_points;
19410 tests[] =
19412 /* upper right */
19414 D3DFVF_XYZB3,
19415 {{0}},
19416 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19417 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19418 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19419 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19420 quad_upper_right_points, quad_upper_right_empty_points
19422 /* center */
19424 D3DFVF_XYZB3,
19425 {{0}},
19426 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19427 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19428 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19429 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
19430 quad_center_points, quad_center_empty_points
19432 /* upper center */
19434 D3DFVF_XYZB3,
19435 {{0}},
19436 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19437 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19438 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19439 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
19440 quad_upper_center_points, quad_upper_center_empty_points
19442 /* full screen */
19444 D3DFVF_XYZB3,
19445 {{0}},
19446 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19447 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19448 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19449 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19450 quad_fullscreen_points, quad_fullscreen_empty_points
19452 /* D3DCOLOR, full screen */
19456 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
19457 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
19458 D3DDECL_END()
19460 {{{{0}}},
19461 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
19462 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
19463 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
19464 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
19465 quad_fullscreen_points, quad_fullscreen_empty_points
19469 window = create_window();
19470 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19471 ok(!!d3d, "Failed to create a D3D object.\n");
19472 if (!(device = create_device(d3d, window, window, TRUE)))
19474 skip("Failed to create a D3D device, skipping tests.\n");
19475 goto done;
19478 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19479 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19480 if (caps.MaxVertexBlendMatrices < 4)
19482 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19483 IDirect3DDevice9_Release(device);
19484 goto done;
19487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19488 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19490 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19491 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19493 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19494 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19495 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19496 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19497 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19498 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19499 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19500 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19505 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19507 const POINT *point;
19509 if (tests[i].fvf)
19511 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
19512 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19513 vertex_declaration = NULL;
19515 else
19517 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
19518 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
19519 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
19520 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
19523 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19524 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19526 hr = IDirect3DDevice9_BeginScene(device);
19527 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19529 if (tests[i].fvf)
19530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19531 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
19532 else
19533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19534 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
19535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19537 hr = IDirect3DDevice9_EndScene(device);
19538 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19540 point = tests[i].quad_points;
19541 while (point->x != -1 && point->y != -1)
19543 color = getPixelColor(device, point->x, point->y);
19544 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19545 ++point;
19548 point = tests[i].empty_points;
19549 while (point->x != -1 && point->y != -1)
19551 color = getPixelColor(device, point->x, point->y);
19552 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19553 ++point;
19556 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19557 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19559 if (vertex_declaration)
19560 IDirect3DVertexDeclaration9_Release(vertex_declaration);
19563 refcount = IDirect3DDevice9_Release(device);
19564 ok(!refcount, "Device has %u references left.\n", refcount);
19566 done:
19567 IDirect3D9_Release(d3d);
19568 DestroyWindow(window);
19571 static void test_updatetexture(void)
19573 IDirect3DDevice9 *device;
19574 IDirect3D9 *d3d9;
19575 HWND window;
19576 HRESULT hr;
19577 IDirect3DBaseTexture9 *src, *dst;
19578 unsigned int t, i, f, l, x, y, z;
19579 D3DLOCKED_RECT locked_rect;
19580 D3DLOCKED_BOX locked_box;
19581 ULONG refcount;
19582 D3DCAPS9 caps;
19583 D3DCOLOR color;
19584 BOOL ati2n_supported, do_visual_test;
19585 static const struct
19587 struct vec3 pos;
19588 struct vec2 texcoord;
19590 quad[] =
19592 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19593 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19594 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19595 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19597 static const struct
19599 struct vec3 pos;
19600 struct vec3 texcoord;
19602 quad_cube_tex[] =
19604 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19605 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19606 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19607 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19609 static const struct
19611 UINT src_width, src_height;
19612 UINT dst_width, dst_height;
19613 UINT src_levels, dst_levels;
19614 D3DFORMAT src_format, dst_format;
19615 BOOL broken;
19617 tests[] =
19619 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19620 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19621 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19622 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19623 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19624 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19625 /* The WARP renderer doesn't handle these cases correctly. */
19626 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19627 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19628 /* Not clear what happens here on Windows, it doesn't make much sense
19629 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19630 * one or something like that). */
19631 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19632 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19633 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19634 /* This one causes weird behavior on Windows (it probably writes out
19635 * of the texture memory). */
19636 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19637 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19638 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19639 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19640 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19641 /* The data is converted correctly on AMD, on Nvidia nothing happens
19642 * (it draws a black quad). */
19643 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19644 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19645 * a 32 bit float on Nvidia (specifically the tested value becomes a
19646 * very small float number which we get as 0 in the test). */
19647 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19648 /* This one doesn't seem to give the expected results on AMD. */
19649 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19650 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19651 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19652 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19654 static const struct
19656 D3DRESOURCETYPE type;
19657 DWORD fvf;
19658 const void *quad;
19659 unsigned int vertex_size;
19660 DWORD cap;
19661 const char *name;
19663 texture_types[] =
19665 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19666 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19668 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19669 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19671 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19672 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19675 window = create_window();
19676 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19677 ok(!!d3d9, "Failed to create a D3D object.\n");
19678 if (!(device = create_device(d3d9, window, window, TRUE)))
19680 skip("Failed to create a D3D device, skipping tests.\n");
19681 IDirect3D9_Release(d3d9);
19682 DestroyWindow(window);
19683 return;
19686 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19687 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19689 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19690 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19691 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19692 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19693 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19694 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19695 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19696 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19698 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19699 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19700 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19701 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19702 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19704 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19706 if (!(caps.TextureCaps & texture_types[t].cap))
19708 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19709 continue;
19712 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19713 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19715 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19716 ati2n_supported = FALSE;
19718 else
19720 ati2n_supported = TRUE;
19723 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19724 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19726 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19728 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19729 continue;
19731 switch (texture_types[t].type)
19733 case D3DRTYPE_TEXTURE:
19734 hr = IDirect3DDevice9_CreateTexture(device,
19735 tests[i].src_width, tests[i].src_height,
19736 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19737 (IDirect3DTexture9 **)&src, NULL);
19738 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19739 hr = IDirect3DDevice9_CreateTexture(device,
19740 tests[i].dst_width, tests[i].dst_height,
19741 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19742 (IDirect3DTexture9 **)&dst, NULL);
19743 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19744 break;
19745 case D3DRTYPE_CUBETEXTURE:
19746 hr = IDirect3DDevice9_CreateCubeTexture(device,
19747 tests[i].src_width,
19748 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19749 (IDirect3DCubeTexture9 **)&src, NULL);
19750 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19751 hr = IDirect3DDevice9_CreateCubeTexture(device,
19752 tests[i].dst_width,
19753 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19754 (IDirect3DCubeTexture9 **)&dst, NULL);
19755 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19756 break;
19757 case D3DRTYPE_VOLUMETEXTURE:
19758 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19759 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19760 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19761 (IDirect3DVolumeTexture9 **)&src, NULL);
19762 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19763 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19764 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19765 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19766 (IDirect3DVolumeTexture9 **)&dst, NULL);
19767 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19768 break;
19769 default:
19770 trace("Unexpected resource type.\n");
19773 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19774 * give a different (and unlikely to be useful) result. */
19775 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19776 && tests[i].src_levels != 0
19777 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19778 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19780 if (do_visual_test)
19782 DWORD *ptr = NULL;
19783 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19785 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19787 width = tests[i].src_width;
19788 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19789 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19791 for (l = 0; l < tests[i].src_levels; ++l)
19793 switch (texture_types[t].type)
19795 case D3DRTYPE_TEXTURE:
19796 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19797 l, &locked_rect, NULL, 0);
19798 ptr = locked_rect.pBits;
19799 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19800 break;
19801 case D3DRTYPE_CUBETEXTURE:
19802 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19803 f, l, &locked_rect, NULL, 0);
19804 ptr = locked_rect.pBits;
19805 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19806 break;
19807 case D3DRTYPE_VOLUMETEXTURE:
19808 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19809 l, &locked_box, NULL, 0);
19810 ptr = locked_box.pBits;
19811 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19812 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19813 break;
19814 default:
19815 trace("Unexpected resource type.\n");
19817 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19819 for (z = 0; z < depth; ++z)
19821 for (y = 0; y < height; ++y)
19823 for (x = 0; x < width; ++x)
19825 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19826 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19827 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19832 switch (texture_types[t].type)
19834 case D3DRTYPE_TEXTURE:
19835 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19836 break;
19837 case D3DRTYPE_CUBETEXTURE:
19838 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19839 break;
19840 case D3DRTYPE_VOLUMETEXTURE:
19841 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19842 break;
19843 default:
19844 trace("Unexpected resource type.\n");
19846 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19848 width >>= 1;
19849 if (!width)
19850 width = 1;
19851 height >>= 1;
19852 if (!height)
19853 height = 1;
19854 depth >>= 1;
19855 if (!depth)
19856 depth = 1;
19861 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
19862 if (FAILED(hr))
19864 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19865 IDirect3DBaseTexture9_Release(src);
19866 IDirect3DBaseTexture9_Release(dst);
19867 continue;
19869 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19871 if (do_visual_test)
19873 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
19874 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
19877 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19879 hr = IDirect3DDevice9_BeginScene(device);
19880 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19882 texture_types[t].quad, texture_types[t].vertex_size);
19883 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19884 hr = IDirect3DDevice9_EndScene(device);
19885 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19887 color = getPixelColor(device, 320, 240);
19888 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
19889 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
19890 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
19893 IDirect3DBaseTexture9_Release(src);
19894 IDirect3DBaseTexture9_Release(dst);
19897 refcount = IDirect3DDevice9_Release(device);
19898 ok(!refcount, "Device has %u references left.\n", refcount);
19899 IDirect3D9_Release(d3d9);
19900 DestroyWindow(window);
19903 static void test_depthbias(void)
19905 IDirect3DDevice9 *device;
19906 IDirect3D9 *d3d;
19907 IDirect3DSurface9 *ds;
19908 D3DCAPS9 caps;
19909 D3DCOLOR color;
19910 ULONG refcount;
19911 HWND window;
19912 HRESULT hr;
19913 unsigned int i;
19914 static const D3DFORMAT formats[] =
19916 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
19918 /* The scaling factor detection function detects the wrong factor for
19919 * float formats on Nvidia, therefore the following tests are disabled.
19920 * The wined3d function detects 2^23 like for fixed point formats but
19921 * the test needs 2^22 to pass.
19923 * AMD GPUs need a different scaling factor for float depth buffers
19924 * (2^24) than fixed point (2^23), but the wined3d detection function
19925 * works there, producing the right result in the test.
19927 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
19931 static const struct
19933 struct vec3 position;
19935 quad[] =
19937 {{-1.0f, -1.0f, 0.0f}},
19938 {{-1.0f, 1.0f, 0.0f}},
19939 {{ 1.0f, -1.0f, 1.0f}},
19940 {{ 1.0f, 1.0f, 1.0f}},
19942 union
19944 float f;
19945 DWORD d;
19946 } conv;
19948 window = create_window();
19949 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19950 ok(!!d3d, "Failed to create a D3D object.\n");
19951 if (!(device = create_device(d3d, window, window, TRUE)))
19953 skip("Failed to create a D3D device, skipping tests.\n");
19954 goto done;
19957 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19958 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19959 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
19961 IDirect3DDevice9_Release(device);
19962 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
19963 goto done;
19966 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19967 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19970 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19971 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19972 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
19973 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19974 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
19975 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19977 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
19979 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19980 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
19982 skip("Depth format %u not supported, skipping.\n", formats[i]);
19983 continue;
19986 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
19987 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
19988 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
19989 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19990 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
19992 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19994 hr = IDirect3DDevice9_BeginScene(device);
19995 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
19998 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19999 conv.f = -0.2f;
20000 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20001 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20003 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20006 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20007 conv.f = 0.0f;
20008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20009 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20010 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20011 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20014 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20015 conv.f = 0.2f;
20016 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20017 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20018 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20019 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20022 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20023 conv.f = 0.4f;
20024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20025 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20027 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20029 color = getPixelColor(device, 61, 240);
20030 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20031 color = getPixelColor(device, 65, 240);
20033 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20034 * a scaling factor based on the first depth format that is used. Other formats with
20035 * a different depth size then render incorrectly. */
20036 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20037 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20038 color = getPixelColor(device, 190, 240);
20039 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20040 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20042 color = getPixelColor(device, 194, 240);
20043 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20044 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20045 color = getPixelColor(device, 318, 240);
20046 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20047 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20049 color = getPixelColor(device, 322, 240);
20050 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20051 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20052 color = getPixelColor(device, 446, 240);
20053 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20054 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20056 color = getPixelColor(device, 450, 240);
20057 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20059 hr = IDirect3DDevice9_EndScene(device);
20060 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20062 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20063 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20064 IDirect3DSurface9_Release(ds);
20067 refcount = IDirect3DDevice9_Release(device);
20068 ok(!refcount, "Device has %u references left.\n", refcount);
20070 done:
20071 IDirect3D9_Release(d3d);
20072 DestroyWindow(window);
20075 static void test_flip(void)
20077 IDirect3DDevice9 *device;
20078 IDirect3D9 *d3d;
20079 ULONG refcount;
20080 HWND window;
20081 HRESULT hr;
20082 IDirect3DSurface9 *back_buffers[3], *test_surface;
20083 unsigned int i;
20084 D3DCOLOR color;
20085 D3DPRESENT_PARAMETERS present_parameters = {0};
20087 window = create_window();
20088 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20089 ok(!!d3d, "Failed to create a D3D object.\n");
20091 present_parameters.BackBufferWidth = 640;
20092 present_parameters.BackBufferHeight = 480;
20093 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20094 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20095 present_parameters.hDeviceWindow = window;
20096 present_parameters.Windowed = TRUE;
20097 present_parameters.BackBufferCount = 3;
20098 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20099 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20100 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20101 if (!device)
20103 skip("Failed to create a D3D device, skipping tests.\n");
20104 IDirect3D9_Release(d3d);
20105 DestroyWindow(window);
20106 return;
20109 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20111 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20112 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20114 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20115 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20116 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20117 IDirect3DSurface9_Release(test_surface);
20119 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20120 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20122 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20123 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20124 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20125 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20127 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20129 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20130 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20132 /* Render target is unmodified. */
20133 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20134 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20135 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20136 IDirect3DSurface9_Release(test_surface);
20138 /* Backbuffer surface pointers are unmodified */
20139 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20141 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20142 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20143 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20144 i, back_buffers[i], test_surface);
20145 IDirect3DSurface9_Release(test_surface);
20148 /* Contents were changed. */
20149 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20150 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20151 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20152 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20155 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20157 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20158 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20160 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20161 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20162 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20163 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20165 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20166 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20168 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20169 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20171 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20172 IDirect3DSurface9_Release(back_buffers[i]);
20174 refcount = IDirect3DDevice9_Release(device);
20175 ok(!refcount, "Device has %u references left.\n", refcount);
20177 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20178 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20180 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20181 goto done;
20184 present_parameters.BackBufferCount = 2;
20185 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20186 present_parameters.Flags = 0;
20187 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20188 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20190 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20192 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20193 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20196 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20197 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20198 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20199 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20201 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20202 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20204 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20205 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20206 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20207 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20208 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20210 color = getPixelColorFromSurface(test_surface, 1, 1);
20211 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20213 IDirect3DSurface9_Release(test_surface);
20214 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20215 IDirect3DSurface9_Release(back_buffers[i]);
20217 refcount = IDirect3DDevice9_Release(device);
20218 ok(!refcount, "Device has %u references left.\n", refcount);
20220 done:
20221 IDirect3D9_Release(d3d);
20222 DestroyWindow(window);
20225 static void test_uninitialized_varyings(void)
20227 static const D3DMATRIX mat =
20229 1.0f, 0.0f, 0.0f, 0.0f,
20230 0.0f, 1.0f, 0.0f, 0.0f,
20231 0.0f, 0.0f, 1.0f, 0.0f,
20232 0.0f, 0.0f, 0.0f, 1.0f,
20233 }}};
20234 static const struct vec3 quad[] =
20236 {-1.0f, -1.0f, 0.1f},
20237 {-1.0f, 1.0f, 0.1f},
20238 { 1.0f, -1.0f, 0.1f},
20239 { 1.0f, 1.0f, 0.1f},
20241 static const DWORD vs1_code[] =
20243 0xfffe0101, /* vs_1_1 */
20244 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20245 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20246 0x0000ffff
20248 static const DWORD vs1_partial_code[] =
20250 0xfffe0101, /* vs_1_1 */
20251 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20252 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20253 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20254 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20255 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20256 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20257 0x0000ffff
20259 static const DWORD vs2_code[] =
20261 0xfffe0200, /* vs_2_0 */
20262 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20263 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20264 0x0000ffff
20266 static const DWORD vs2_partial_code[] =
20268 0xfffe0200, /* vs_2_0 */
20269 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20270 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20271 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20272 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20273 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20274 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20275 0x0000ffff
20277 static const DWORD vs3_code[] =
20279 0xfffe0300, /* vs_3_0 */
20280 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20281 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20282 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20283 0x0000ffff
20285 static const DWORD vs3_partial_code[] =
20287 0xfffe0300, /* vs_3_0 */
20288 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20289 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20290 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20291 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20292 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20293 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20294 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20295 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20296 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20297 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20298 0x0000ffff
20300 static const DWORD ps1_diffuse_code[] =
20302 0xffff0101, /* ps_1_1 */
20303 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20304 0x0000ffff
20306 static const DWORD ps1_specular_code[] =
20308 0xffff0101, /* ps_1_1 */
20309 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20310 0x0000ffff
20312 static const DWORD ps1_texcoord_code[] =
20314 0xffff0101, /* ps_1_1 */
20315 0x00000040, 0xb00f0000, /* texcoord t0 */
20316 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20317 0x0000ffff
20319 static const DWORD ps2_diffuse_code[] =
20321 0xffff0200, /* ps_2_0 */
20322 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20323 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20324 0x0000ffff
20326 static const DWORD ps2_specular_code[] =
20328 0xffff0200, /* ps_2_0 */
20329 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20330 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20331 0x0000ffff
20333 static const DWORD ps2_texcoord_code[] =
20335 0xffff0200, /* ps_2_0 */
20336 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20337 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20338 0x0000ffff
20340 static const DWORD ps3_diffuse_code[] =
20342 0xffff0300, /* ps_3_0 */
20343 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20344 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20345 0x0000ffff
20347 static const DWORD ps3_specular_code[] =
20349 0xffff0300, /* ps_3_0 */
20350 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20351 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20352 0x0000ffff
20354 static const DWORD ps3_texcoord_code[] =
20356 0xffff0300, /* ps_3_0 */
20357 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20358 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20359 0x0000ffff
20361 static const struct
20363 DWORD vs_version;
20364 const DWORD *vs;
20365 DWORD ps_version;
20366 const DWORD *ps;
20367 D3DCOLOR expected;
20368 BOOL allow_zero_alpha;
20369 BOOL allow_zero;
20370 BOOL broken_warp;
20372 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20373 * while on Nvidia it's the opposite. Just allow both. */
20374 tests[] =
20376 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20377 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20378 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20379 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20380 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20381 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20382 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20383 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20384 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20385 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, TRUE},
20386 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x00000000, FALSE, FALSE, TRUE},
20387 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0x00000000, FALSE, FALSE, TRUE},
20388 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, FALSE, TRUE},
20389 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20390 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
20391 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
20392 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20393 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE},
20394 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE},
20395 /* Fails on Radeon HD 2600 with 0x008000ff aka nonsensical color. */
20396 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE}, */
20397 /* Randomly fails on Radeon HD 2600. */
20398 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000}, */
20399 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE},
20401 IDirect3DDevice9 *device;
20402 IDirect3D9 *d3d;
20403 HWND window;
20404 HRESULT hr;
20405 D3DADAPTER_IDENTIFIER9 identifier;
20406 IDirect3DSurface9 *backbuffer;
20407 struct surface_readback rb;
20408 IDirect3DVertexShader9 *vs;
20409 IDirect3DPixelShader9 *ps;
20410 unsigned int i;
20411 ULONG refcount;
20412 D3DCAPS9 caps;
20413 D3DCOLOR color;
20414 BOOL warp;
20416 window = create_window();
20417 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20418 ok(!!d3d, "Failed to create a D3D object.\n");
20419 if (!(device = create_device(d3d, window, window, TRUE)))
20421 skip("Failed to create a D3D device, skipping tests.\n");
20422 IDirect3D9_Release(d3d);
20423 DestroyWindow(window);
20424 return;
20427 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20428 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20429 warp = adapter_is_warp(&identifier);
20431 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20432 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20434 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20435 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20437 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20438 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20439 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20440 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20441 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20442 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20444 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20446 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20448 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20450 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20452 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20454 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20455 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20457 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20459 if (caps.VertexShaderVersion < tests[i].vs_version
20460 || caps.PixelShaderVersion < tests[i].ps_version)
20462 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20463 continue;
20465 if (tests[i].vs)
20467 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20468 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20470 else
20472 vs = NULL;
20474 if (tests[i].ps)
20476 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20477 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20479 else
20481 ps = NULL;
20484 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20485 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20486 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20487 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20489 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20490 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20492 hr = IDirect3DDevice9_BeginScene(device);
20493 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20496 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20498 hr = IDirect3DDevice9_EndScene(device);
20499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20501 get_rt_readback(backbuffer, &rb);
20502 color = get_readback_color(&rb, 320, 240);
20503 ok(color_match(color, tests[i].expected, 1)
20504 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20505 || (tests[i].allow_zero && !color) || (broken(warp && tests[i].broken_warp)),
20506 "Got unexpected color 0x%08x, case %u.\n", color, i);
20507 release_surface_readback(&rb);
20509 if (vs)
20510 IDirect3DVertexShader9_Release(vs);
20511 if (ps)
20512 IDirect3DVertexShader9_Release(ps);
20515 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20516 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20518 IDirect3DSurface9_Release(backbuffer);
20519 refcount = IDirect3DDevice9_Release(device);
20520 ok(!refcount, "Device has %u references left.\n", refcount);
20521 IDirect3D9_Release(d3d);
20522 DestroyWindow(window);
20525 static void test_multisample_init(void)
20527 IDirect3DDevice9 *device;
20528 IDirect3D9 *d3d;
20529 IDirect3DSurface9 *back, *multi;
20530 ULONG refcount;
20531 HWND window;
20532 HRESULT hr;
20533 D3DCOLOR color;
20534 unsigned int x, y;
20535 struct surface_readback rb;
20536 BOOL all_zero = TRUE;
20538 window = create_window();
20539 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20540 ok(!!d3d, "Failed to create a D3D object.\n");
20542 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20543 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20545 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20546 goto done;
20549 if (!(device = create_device(d3d, window, window, TRUE)))
20551 skip("Failed to create a D3D device, skipping tests.\n");
20552 goto done;
20555 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20556 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20557 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20558 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20559 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20561 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20562 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20564 get_rt_readback(back, &rb);
20565 for (y = 0; y < 480; ++y)
20567 for (x = 0; x < 640; x++)
20569 color = get_readback_color(&rb, x, y);
20570 if (!color_match(color, 0x00000000, 0))
20572 all_zero = FALSE;
20573 break;
20576 if (!all_zero)
20577 break;
20579 release_surface_readback(&rb);
20580 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20582 IDirect3DSurface9_Release(multi);
20583 IDirect3DSurface9_Release(back);
20585 refcount = IDirect3DDevice9_Release(device);
20586 ok(!refcount, "Device has %u references left.\n", refcount);
20588 done:
20589 IDirect3D9_Release(d3d);
20590 DestroyWindow(window);
20593 static void test_texture_blending(void)
20595 #define STATE_END() {0xffffffff, 0xffffffff}
20596 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20598 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20599 IDirect3DSurface9 *backbuffer;
20600 struct surface_readback rb;
20601 D3DLOCKED_RECT locked_rect;
20602 IDirect3DDevice9 *device;
20603 unsigned int i, j, k;
20604 IDirect3D9 *d3d;
20605 D3DCOLOR color;
20606 ULONG refcount;
20607 D3DCAPS9 caps;
20608 HWND window;
20609 HRESULT hr;
20611 static const struct
20613 struct vec3 position;
20614 DWORD diffuse;
20616 quad[] =
20618 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20619 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20620 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20621 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20624 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
20626 struct texture_stage_state
20628 D3DTEXTURESTAGESTATETYPE name;
20629 DWORD value;
20632 struct texture_stage
20634 enum
20636 TEXTURE_INVALID,
20637 TEXTURE_NONE,
20638 TEXTURE_BUMPMAP,
20639 TEXTURE_RED,
20641 texture;
20642 struct texture_stage_state state[20];
20645 static const struct texture_stage default_stage_state =
20647 TEXTURE_NONE,
20649 {D3DTSS_COLOROP, D3DTOP_DISABLE},
20650 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20651 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20652 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
20653 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20654 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
20655 {D3DTSS_BUMPENVMAT00, 0},
20656 {D3DTSS_BUMPENVMAT01, 0},
20657 {D3DTSS_BUMPENVMAT10, 0},
20658 {D3DTSS_BUMPENVMAT11, 0},
20659 {D3DTSS_BUMPENVLSCALE, 0},
20660 {D3DTSS_BUMPENVLOFFSET, 0},
20661 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
20662 {D3DTSS_COLORARG0, D3DTA_CURRENT},
20663 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
20664 {D3DTSS_RESULTARG, D3DTA_CURRENT},
20665 {D3DTSS_CONSTANT, 0},
20666 STATE_END(),
20670 const struct test
20672 DWORD tex_op_caps;
20673 D3DCOLOR expected_color;
20674 struct texture_stage stage[8];
20676 tests[] =
20679 D3DTEXOPCAPS_DISABLE,
20680 0x80ffff02,
20683 TEXTURE_NONE,
20685 STATE_END(),
20691 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20692 0x80ffff02,
20695 TEXTURE_NONE,
20697 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20698 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20699 STATE_END(),
20702 {TEXTURE_INVALID}
20706 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20707 0x80ffff02,
20710 TEXTURE_NONE,
20712 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20713 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20714 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20715 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20716 STATE_END(),
20722 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20723 0x80ffff02,
20726 TEXTURE_NONE,
20728 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20729 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
20730 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20731 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20732 STATE_END(),
20738 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20739 0x00000000,
20742 TEXTURE_NONE,
20744 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20745 {D3DTSS_COLORARG1, D3DTA_TEMP},
20746 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20747 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20748 STATE_END(),
20754 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20755 0x80f0f000,
20758 TEXTURE_NONE,
20760 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20761 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20762 STATE_END(),
20766 TEXTURE_NONE,
20768 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20769 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20770 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20771 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20772 STATE_END(),
20775 {TEXTURE_INVALID}
20779 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20780 0x71f0f000,
20783 TEXTURE_NONE,
20785 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20786 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20787 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20788 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20789 STATE_END(),
20793 TEXTURE_NONE,
20795 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20796 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20797 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20798 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
20799 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20800 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
20801 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20802 STATE_END(),
20805 {TEXTURE_INVALID}
20810 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20811 0x80ff0000,
20814 TEXTURE_BUMPMAP,
20816 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20817 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20818 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20819 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20820 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20821 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20822 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20823 STATE_END(),
20828 TEXTURE_RED,
20830 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20831 STATE_END(),
20834 {TEXTURE_INVALID}
20838 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20839 0x80ff0000,
20842 TEXTURE_BUMPMAP,
20844 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20845 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20846 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20847 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20848 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20849 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20850 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20851 STATE_END(),
20855 TEXTURE_RED,
20857 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20858 STATE_END(),
20861 {TEXTURE_INVALID}
20865 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20866 0x80ff0000,
20869 TEXTURE_BUMPMAP,
20871 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20872 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20873 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20874 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20875 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20876 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20877 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20878 STATE_END(),
20882 TEXTURE_RED,
20884 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20885 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20886 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20887 STATE_END(),
20890 {TEXTURE_INVALID}
20894 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20895 0x00ff0000,
20898 TEXTURE_BUMPMAP,
20900 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20901 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20902 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20903 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20904 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20905 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20906 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20907 STATE_END(),
20911 TEXTURE_RED,
20913 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20914 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20915 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20916 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20917 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20918 STATE_END(),
20921 {TEXTURE_INVALID}
20925 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20926 0x80ff0000,
20929 TEXTURE_BUMPMAP,
20931 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20932 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20933 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20934 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20935 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20936 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20937 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20938 STATE_END(),
20942 TEXTURE_RED,
20944 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20945 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20946 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20947 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20948 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20949 STATE_END(),
20952 {TEXTURE_INVALID}
20957 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
20958 | D3DTEXOPCAPS_ADD,
20959 0x80ff0000,
20962 TEXTURE_BUMPMAP,
20964 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20965 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20966 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20967 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20968 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20969 {D3DTSS_ALPHAOP, D3DTOP_ADD},
20970 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20971 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
20972 {D3DTSS_CONSTANT, 0x0fffffff},
20973 STATE_END(),
20977 TEXTURE_RED,
20979 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20980 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20981 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20982 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20983 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20984 STATE_END(),
20987 {TEXTURE_INVALID}
20991 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
20992 | D3DTEXOPCAPS_MODULATE2X,
20993 0x80ff0000,
20996 TEXTURE_BUMPMAP,
20998 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20999 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21000 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21001 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21002 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21003 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21004 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21005 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21006 {D3DTSS_CONSTANT, 0x01ffffff},
21007 STATE_END(),
21011 TEXTURE_RED,
21013 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21014 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21015 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21016 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21017 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21018 STATE_END(),
21021 {TEXTURE_INVALID}
21025 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21026 | D3DTEXOPCAPS_MODULATE2X,
21027 0x80ffff00,
21030 TEXTURE_BUMPMAP,
21032 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21033 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21034 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21035 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21036 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21037 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21038 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21039 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21040 {D3DTSS_CONSTANT, 0x01ffffff},
21041 STATE_END(),
21045 TEXTURE_RED,
21047 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21048 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21049 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21050 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21051 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21052 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21053 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21054 STATE_END(),
21057 {TEXTURE_INVALID}
21061 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21062 0x01234567,
21065 TEXTURE_NONE,
21067 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21068 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21069 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21070 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21071 {D3DTSS_RESULTARG, D3DTA_TEMP},
21072 {D3DTSS_CONSTANT, 0x01234567},
21073 STATE_END(),
21077 TEXTURE_BUMPMAP,
21079 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21080 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21081 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21082 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21083 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21084 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21085 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21086 {D3DTSS_RESULTARG, D3DTA_TEMP},
21087 STATE_END(),
21091 TEXTURE_RED,
21093 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21094 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21095 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21096 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21097 STATE_END(),
21101 TEXTURE_NONE,
21103 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21104 {D3DTSS_COLORARG1, D3DTA_TEMP},
21105 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21106 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21107 STATE_END(),
21110 {TEXTURE_INVALID}
21114 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21115 0x00234567,
21118 TEXTURE_NONE,
21120 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21121 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21122 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21123 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21124 {D3DTSS_RESULTARG, D3DTA_TEMP},
21125 {D3DTSS_CONSTANT, 0x01234567},
21126 STATE_END(),
21130 TEXTURE_BUMPMAP,
21132 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21133 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21134 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21135 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21136 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21137 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21138 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21139 STATE_END(),
21143 TEXTURE_RED,
21145 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21146 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21147 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21148 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21149 STATE_END(),
21153 TEXTURE_NONE,
21155 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21156 {D3DTSS_COLORARG1, D3DTA_TEMP},
21157 STATE_END(),
21160 {TEXTURE_INVALID}
21164 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21165 0x01234567,
21168 TEXTURE_NONE,
21170 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21171 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21172 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21173 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21174 {D3DTSS_RESULTARG, D3DTA_TEMP},
21175 {D3DTSS_CONSTANT, 0x01234567},
21176 STATE_END(),
21180 TEXTURE_BUMPMAP,
21182 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21183 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21184 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21185 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21186 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21187 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21188 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21189 {D3DTSS_RESULTARG, D3DTA_TEMP},
21190 STATE_END(),
21194 TEXTURE_RED,
21196 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21197 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21198 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21199 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21200 STATE_END(),
21204 TEXTURE_NONE,
21206 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21207 {D3DTSS_COLORARG1, D3DTA_TEMP},
21208 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21209 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21210 STATE_END(),
21213 {TEXTURE_INVALID}
21217 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21218 0x01234567,
21221 TEXTURE_NONE,
21223 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21224 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21225 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21226 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21227 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21228 {D3DTSS_CONSTANT, 0x01234567},
21229 STATE_END(),
21233 TEXTURE_BUMPMAP,
21235 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21236 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21237 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21238 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21239 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21240 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21241 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21242 {D3DTSS_RESULTARG, D3DTA_TEMP},
21243 STATE_END(),
21247 TEXTURE_RED,
21249 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21250 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21251 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21252 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21253 {D3DTSS_RESULTARG, D3DTA_TEMP},
21254 STATE_END(),
21258 TEXTURE_NONE,
21260 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21261 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21262 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21263 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21264 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21265 STATE_END(),
21268 {TEXTURE_INVALID}
21273 window = create_window();
21274 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21275 ok(!!d3d, "Failed to create a D3D object.\n");
21276 if (!(device = create_device(d3d, window, window, TRUE)))
21278 skip("Failed to create a D3D device.\n");
21279 goto done;
21282 memset(&caps, 0, sizeof(caps));
21283 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21284 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21286 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21288 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21289 IDirect3DDevice9_Release(device);
21290 goto done;
21293 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21295 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21296 IDirect3DDevice9_Release(device);
21297 goto done;
21300 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21301 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21303 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21304 IDirect3DDevice9_Release(device);
21305 goto done;
21308 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21309 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21311 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21312 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21313 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21314 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21316 memset(&locked_rect, 0, sizeof(locked_rect));
21317 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21318 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21319 *((WORD *)locked_rect.pBits) = 0xff00;
21320 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21321 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21323 memset(&locked_rect, 0, sizeof(locked_rect));
21324 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21325 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21326 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21327 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21328 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21330 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21331 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21333 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21335 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21337 const struct test *current_test = &tests[i];
21339 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21341 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21342 continue;
21345 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21347 IDirect3DTexture9 *current_texture = NULL;
21349 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21351 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21352 default_stage_state.state[k].name, default_stage_state.state[k].value);
21353 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21356 if (current_test->stage[j].texture != TEXTURE_INVALID)
21358 const struct texture_stage_state *current_state = current_test->stage[j].state;
21360 switch (current_test->stage[j].texture)
21362 case TEXTURE_RED:
21363 current_texture = texture_red;
21364 break;
21365 case TEXTURE_BUMPMAP:
21366 current_texture = texture_bumpmap;
21367 break;
21368 default:
21369 current_texture = NULL;
21370 break;
21373 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21375 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21376 current_state[k].name, current_state[k].value);
21377 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21381 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21382 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21386 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21388 hr = IDirect3DDevice9_BeginScene(device);
21389 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21391 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21392 hr = IDirect3DDevice9_EndScene(device);
21393 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21395 get_rt_readback(backbuffer, &rb);
21396 color = get_readback_color(&rb, 320, 240);
21397 ok(color_match(color, current_test->expected_color, 1),
21398 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21399 release_surface_readback(&rb);
21400 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21401 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21404 IDirect3DTexture9_Release(texture_bumpmap);
21405 IDirect3DTexture9_Release(texture_red);
21406 IDirect3DSurface9_Release(backbuffer);
21407 refcount = IDirect3DDevice9_Release(device);
21408 ok(!refcount, "Device has %u references left.\n", refcount);
21409 done:
21410 IDirect3D9_Release(d3d);
21411 DestroyWindow(window);
21414 static void test_color_clamping(void)
21416 static const D3DMATRIX mat =
21418 1.0f, 0.0f, 0.0f, 0.0f,
21419 0.0f, 1.0f, 0.0f, 0.0f,
21420 0.0f, 0.0f, 1.0f, 0.0f,
21421 0.0f, 0.0f, 0.0f, 1.0f,
21422 }}};
21423 static const struct vec3 quad[] =
21425 {-1.0f, -1.0f, 0.1f},
21426 {-1.0f, 1.0f, 0.1f},
21427 { 1.0f, -1.0f, 0.1f},
21428 { 1.0f, 1.0f, 0.1f},
21430 static const DWORD vs1_code[] =
21432 0xfffe0101, /* vs_1_1 */
21433 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21434 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21435 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21436 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21437 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21438 0x0000ffff
21440 static const DWORD vs2_code[] =
21442 0xfffe0200, /* vs_2_0 */
21443 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21444 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21445 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21446 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21447 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21448 0x0000ffff
21450 static const DWORD vs3_code[] =
21452 0xfffe0300, /* vs_3_0 */
21453 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21454 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21455 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21456 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
21457 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21458 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21459 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
21460 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
21461 0x0000ffff
21463 static const DWORD ps1_code[] =
21465 0xffff0101, /* ps_1_1 */
21466 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21467 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
21468 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21469 0x0000ffff
21471 static const DWORD ps2_code[] =
21473 0xffff0200, /* ps_2_0 */
21474 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
21475 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
21476 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21477 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21478 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21479 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21480 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
21481 0x0000ffff
21483 static const DWORD ps3_code[] =
21485 0xffff0300, /* ps_3_0 */
21486 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21487 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
21488 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21489 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21490 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21491 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
21492 0x0000ffff
21494 static const struct
21496 DWORD vs_version;
21497 const DWORD *vs;
21498 DWORD ps_version;
21499 const DWORD *ps;
21500 D3DCOLOR expected, broken;
21502 tests[] =
21504 {0, NULL, 0, NULL, 0x00404040},
21505 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
21506 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
21507 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
21508 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
21509 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
21511 IDirect3DVertexShader9 *vs;
21512 IDirect3DPixelShader9 *ps;
21513 IDirect3DDevice9 *device;
21514 IDirect3D9 *d3d9;
21515 unsigned int i;
21516 ULONG refcount;
21517 D3DCOLOR color;
21518 D3DCAPS9 caps;
21519 HWND window;
21520 HRESULT hr;
21522 window = create_window();
21523 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21524 ok(!!d3d9, "Failed to create a D3D object.\n");
21525 if (!(device = create_device(d3d9, window, window, TRUE)))
21527 skip("Failed to create a D3D device, skipping tests.\n");
21528 IDirect3D9_Release(d3d9);
21529 DestroyWindow(window);
21530 return;
21533 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21534 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21536 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
21537 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
21538 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
21539 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
21540 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
21541 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
21542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21543 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21545 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
21547 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
21548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
21549 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
21550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
21551 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
21552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21553 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
21556 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
21557 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
21558 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21559 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21560 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21561 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
21562 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21563 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
21564 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21565 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
21566 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21567 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21568 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21570 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
21571 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21573 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
21575 if (caps.VertexShaderVersion < tests[i].vs_version
21576 || caps.PixelShaderVersion < tests[i].ps_version)
21578 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
21579 continue;
21581 if (tests[i].vs)
21583 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
21584 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
21586 else
21588 vs = NULL;
21590 if (tests[i].ps)
21592 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
21593 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
21595 else
21597 ps = NULL;
21600 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21601 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21602 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21603 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21605 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
21606 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21608 hr = IDirect3DDevice9_BeginScene(device);
21609 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21612 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21614 hr = IDirect3DDevice9_EndScene(device);
21615 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21617 color = getPixelColor(device, 320, 240);
21618 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
21619 "Got unexpected color 0x%08x, case %u.\n", color, i);
21621 if (vs)
21622 IDirect3DVertexShader9_Release(vs);
21623 if (ps)
21624 IDirect3DVertexShader9_Release(ps);
21627 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21628 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
21630 refcount = IDirect3DDevice9_Release(device);
21631 ok(!refcount, "Device has %u references left.\n", refcount);
21632 IDirect3D9_Release(d3d9);
21633 DestroyWindow(window);
21636 static void test_line_antialiasing_blending(void)
21638 IDirect3DDevice9 *device;
21639 IDirect3D9 *d3d9;
21640 ULONG refcount;
21641 D3DCOLOR color;
21642 D3DCAPS9 caps;
21643 HWND window;
21644 HRESULT hr;
21646 static const struct
21648 struct vec3 position;
21649 DWORD diffuse;
21651 green_quad[] =
21653 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21654 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21655 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21656 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21658 static const struct
21660 struct vec3 position;
21661 DWORD diffuse;
21663 red_quad[] =
21665 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21666 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21667 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21668 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21671 window = create_window();
21672 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21673 ok(!!d3d9, "Failed to create a D3D object.\n");
21674 if (!(device = create_device(d3d9, window, window, TRUE)))
21676 skip("Failed to create a D3D device.\n");
21677 IDirect3D9_Release(d3d9);
21678 DestroyWindow(window);
21679 return;
21682 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21683 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21684 trace("Line antialiasing support: %#x.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
21686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21687 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21689 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21691 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21693 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
21694 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
21695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
21696 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
21697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
21698 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
21699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
21700 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
21702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
21703 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21704 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21705 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21706 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
21707 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
21708 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
21709 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
21711 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21712 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21714 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21715 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21716 hr = IDirect3DDevice9_BeginScene(device);
21717 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21720 hr = IDirect3DDevice9_EndScene(device);
21721 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21722 color = getPixelColor(device, 320, 240);
21723 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21725 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21726 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21727 hr = IDirect3DDevice9_BeginScene(device);
21728 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21730 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21731 hr = IDirect3DDevice9_EndScene(device);
21732 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21733 color = getPixelColor(device, 320, 240);
21734 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21736 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
21737 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
21739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21740 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21741 hr = IDirect3DDevice9_BeginScene(device);
21742 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21744 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21745 hr = IDirect3DDevice9_EndScene(device);
21746 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21747 color = getPixelColor(device, 320, 240);
21748 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21750 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21751 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21752 hr = IDirect3DDevice9_BeginScene(device);
21753 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21755 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21756 hr = IDirect3DDevice9_EndScene(device);
21757 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21758 color = getPixelColor(device, 320, 240);
21759 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
21762 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#x.\n", hr);
21764 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21765 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21766 hr = IDirect3DDevice9_BeginScene(device);
21767 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21769 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21770 hr = IDirect3DDevice9_EndScene(device);
21771 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21772 color = getPixelColor(device, 320, 240);
21773 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21775 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21776 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21777 hr = IDirect3DDevice9_BeginScene(device);
21778 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21780 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21781 hr = IDirect3DDevice9_EndScene(device);
21782 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21783 color = getPixelColor(device, 320, 240);
21784 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21786 refcount = IDirect3DDevice9_Release(device);
21787 ok(!refcount, "Device has %u references left.\n", refcount);
21788 IDirect3D9_Release(d3d9);
21789 DestroyWindow(window);
21792 static void test_dsy(void)
21794 static const DWORD vs_code[] =
21796 0xfffe0300, /* vs_3_0 */
21797 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21798 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
21799 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21800 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21801 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21802 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
21803 0x0000ffff
21805 static const DWORD ps_code[] =
21807 0xffff0300, /* ps_3_0 */
21808 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21809 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
21810 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
21811 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
21812 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
21813 0x0000ffff
21815 static const struct
21817 struct vec3 pos;
21818 D3DCOLOR color;
21820 quad[] =
21822 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
21823 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
21824 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
21825 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
21827 IDirect3DSurface9 *backbuffer, *rt;
21828 IDirect3DVertexShader9 *vs;
21829 IDirect3DPixelShader9 *ps;
21830 IDirect3DDevice9 *device;
21831 IDirect3D9 *d3d;
21832 ULONG refcount;
21833 D3DCAPS9 caps;
21834 DWORD color;
21835 HWND window;
21836 HRESULT hr;
21838 window = create_window();
21839 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21840 ok(!!d3d, "Failed to create a D3D object.\n");
21841 if (!(device = create_device(d3d, window, window, TRUE)))
21843 skip("Failed to create a D3D device, skipping tests.\n");
21844 goto done;
21847 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21848 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
21849 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
21851 skip("No ps_3_0 support, skipping dsy tests.\n");
21852 IDirect3DDevice9_Release(device);
21853 goto done;
21856 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21857 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
21859 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
21860 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
21861 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr);
21862 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21863 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
21865 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
21866 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
21867 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
21868 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
21870 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21871 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21872 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21873 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21874 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21875 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21877 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
21878 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21879 hr = IDirect3DDevice9_BeginScene(device);
21880 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21882 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
21883 hr = IDirect3DDevice9_EndScene(device);
21884 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21886 color = getPixelColor(device, 360, 240);
21887 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
21889 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
21890 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
21892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
21893 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21894 hr = IDirect3DDevice9_BeginScene(device);
21895 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21897 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
21898 hr = IDirect3DDevice9_EndScene(device);
21899 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21901 color = getPixelColor(device, 360, 240);
21902 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
21904 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21905 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
21907 IDirect3DSurface9_Release(rt);
21908 IDirect3DSurface9_Release(backbuffer);
21909 IDirect3DVertexShader9_Release(vs);
21910 IDirect3DPixelShader9_Release(ps);
21912 refcount = IDirect3DDevice9_Release(device);
21913 ok(!refcount, "Device has %u references left.\n", refcount);
21914 done:
21915 IDirect3D9_Release(d3d);
21916 DestroyWindow(window);
21919 static void test_evict_bound_resources(void)
21921 IDirect3DVertexBuffer9 *vb;
21922 IDirect3DIndexBuffer9 *ib;
21923 IDirect3DDevice9 *device;
21924 IDirect3D9 *d3d9;
21925 ULONG refcount;
21926 D3DCOLOR color;
21927 HWND window;
21928 void *data;
21929 HRESULT hr;
21931 static const struct
21933 struct vec3 position;
21934 DWORD diffuse;
21936 green_quad[] =
21938 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21939 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21940 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21941 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21943 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
21945 window = create_window();
21946 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21947 ok(!!d3d9, "Failed to create a D3D object.\n");
21949 if (!(device = create_device(d3d9, window, window, TRUE)))
21951 skip("Failed to create a D3D device.\n");
21952 IDirect3D9_Release(d3d9);
21953 DestroyWindow(window);
21954 return;
21957 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
21958 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
21959 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
21961 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
21962 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
21963 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
21965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21966 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21968 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21970 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21972 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21973 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21975 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
21976 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
21977 memcpy(data, green_quad, sizeof(green_quad));
21978 hr = IDirect3DVertexBuffer9_Unlock(vb);
21979 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
21981 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
21982 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
21983 memcpy(data, indices, sizeof(indices));
21984 hr = IDirect3DIndexBuffer9_Unlock(ib);
21985 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
21987 hr = IDirect3DDevice9_SetIndices(device, ib);
21988 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
21989 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
21990 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
21992 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
21993 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21994 hr = IDirect3DDevice9_BeginScene(device);
21995 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21996 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
21997 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21998 hr = IDirect3DDevice9_EndScene(device);
21999 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22000 color = getPixelColor(device, 320, 240);
22001 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22003 hr = IDirect3DDevice9_EvictManagedResources(device);
22004 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#x.\n", hr);
22006 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22007 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22008 hr = IDirect3DDevice9_BeginScene(device);
22009 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22010 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22011 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22012 hr = IDirect3DDevice9_EndScene(device);
22013 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22014 color = getPixelColor(device, 320, 240);
22015 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22017 IDirect3DIndexBuffer9_Release(ib);
22018 IDirect3DVertexBuffer9_Release(vb);
22019 refcount = IDirect3DDevice9_Release(device);
22020 ok(!refcount, "Device has %u references left.\n", refcount);
22021 IDirect3D9_Release(d3d9);
22022 DestroyWindow(window);
22025 /* This test shows that 0xffff is valid index in D3D9. */
22026 static void test_max_index16(void)
22028 static const struct vertex
22030 struct vec3 position;
22031 DWORD diffuse;
22033 green_quad[] =
22035 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22036 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22037 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22038 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22040 static const unsigned short indices[] = {0, 1, 2, 0xffff};
22041 static const unsigned int vertex_count = 0xffff + 1;
22043 D3DADAPTER_IDENTIFIER9 identifier;
22044 IDirect3DVertexBuffer9 *vb;
22045 IDirect3DIndexBuffer9 *ib;
22046 IDirect3DDevice9 *device;
22047 struct vertex *vb_data;
22048 IDirect3D9 *d3d9;
22049 ULONG refcount;
22050 D3DCOLOR color;
22051 D3DCAPS9 caps;
22052 HWND window;
22053 void *data;
22054 HRESULT hr;
22055 BOOL warp;
22057 window = create_window();
22058 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22059 ok(!!d3d9, "Failed to create a D3D object.\n");
22061 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
22062 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22063 warp = adapter_is_warp(&identifier);
22065 if (!(device = create_device(d3d9, window, window, TRUE)))
22067 skip("Failed to create a D3D device.\n");
22068 IDirect3D9_Release(d3d9);
22069 DestroyWindow(window);
22070 return;
22073 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22074 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22075 if (caps.MaxVertexIndex < 0xffff)
22077 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
22078 IDirect3DDevice9_Release(device);
22079 IDirect3D9_Release(d3d9);
22080 DestroyWindow(window);
22081 return;
22084 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
22085 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22086 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22088 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22089 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22090 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22093 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22095 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22097 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22099 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22100 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22102 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
22103 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22104 vb_data[0] = green_quad[0];
22105 vb_data[1] = green_quad[1];
22106 vb_data[2] = green_quad[2];
22107 vb_data[0xffff] = green_quad[3];
22108 hr = IDirect3DVertexBuffer9_Unlock(vb);
22109 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22111 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22112 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22113 memcpy(data, indices, sizeof(indices));
22114 hr = IDirect3DIndexBuffer9_Unlock(ib);
22115 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22117 hr = IDirect3DDevice9_SetIndices(device, ib);
22118 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22119 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
22120 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22122 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22123 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22124 hr = IDirect3DDevice9_BeginScene(device);
22125 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22126 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
22127 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22128 hr = IDirect3DDevice9_EndScene(device);
22129 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22130 color = getPixelColor(device, 20, 20);
22131 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22132 color = getPixelColor(device, 320, 240);
22133 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22134 color = getPixelColor(device, 620, 460);
22135 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22137 IDirect3DIndexBuffer9_Release(ib);
22138 IDirect3DVertexBuffer9_Release(vb);
22139 refcount = IDirect3DDevice9_Release(device);
22140 ok(!refcount, "Device has %u references left.\n", refcount);
22141 IDirect3D9_Release(d3d9);
22142 DestroyWindow(window);
22145 static void test_backbuffer_resize(void)
22147 D3DPRESENT_PARAMETERS present_parameters = {0};
22148 IDirect3DSurface9 *backbuffer;
22149 IDirect3DDevice9 *device;
22150 IDirect3D9 *d3d;
22151 D3DCOLOR color;
22152 ULONG refcount;
22153 HWND window;
22154 HRESULT hr;
22156 static const struct
22158 struct vec3 position;
22159 DWORD diffuse;
22161 quad[] =
22163 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22164 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22165 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22166 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22169 window = create_window();
22170 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22171 ok(!!d3d, "Failed to create a D3D object.\n");
22172 if (!(device = create_device(d3d, window, window, TRUE)))
22174 skip("Failed to create a D3D device.\n");
22175 goto done;
22178 /* Wine d3d9 implementation had a bug which was triggered by a
22179 * SetRenderTarget() call with an unreferenced surface. */
22180 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22181 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22182 refcount = IDirect3DSurface9_Release(backbuffer);
22183 ok(!refcount, "Surface has %u references left.\n", refcount);
22184 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22185 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22186 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22187 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
22190 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22191 color = getPixelColor(device, 1, 1);
22192 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
22194 present_parameters.BackBufferWidth = 800;
22195 present_parameters.BackBufferHeight = 600;
22196 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22197 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22198 present_parameters.hDeviceWindow = NULL;
22199 present_parameters.Windowed = TRUE;
22200 present_parameters.EnableAutoDepthStencil = TRUE;
22201 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22202 hr = IDirect3DDevice9_Reset(device, &present_parameters);
22203 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
22205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22206 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22208 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22210 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22211 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22212 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22214 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22215 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22216 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22217 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22218 IDirect3DSurface9_Release(backbuffer);
22220 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
22221 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22222 color = getPixelColor(device, 1, 1);
22223 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22224 color = getPixelColor(device, 700, 500);
22225 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22227 hr = IDirect3DDevice9_BeginScene(device);
22228 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22230 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22231 hr = IDirect3DDevice9_EndScene(device);
22232 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22233 color = getPixelColor(device, 1, 1);
22234 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22235 color = getPixelColor(device, 700, 500);
22236 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22238 refcount = IDirect3DDevice9_Release(device);
22239 ok(!refcount, "Device has %u references left.\n", refcount);
22240 done:
22241 IDirect3D9_Release(d3d);
22242 DestroyWindow(window);
22245 static void test_drawindexedprimitiveup(void)
22247 static const struct vertex
22249 struct vec3 position;
22250 DWORD diffuse;
22252 quad[] =
22254 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
22255 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
22256 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22257 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
22259 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
22260 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
22261 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22262 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
22264 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
22265 IDirect3DDevice9 *device;
22266 IDirect3D9 *d3d;
22267 ULONG refcount;
22268 D3DCOLOR color;
22269 HWND window;
22270 HRESULT hr;
22272 window = create_window();
22273 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22274 ok(!!d3d, "Failed to create a D3D object.\n");
22276 if (!(device = create_device(d3d, window, window, TRUE)))
22278 skip("Failed to create a D3D device.\n");
22279 IDirect3D9_Release(d3d);
22280 DestroyWindow(window);
22281 return;
22284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22285 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22287 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22289 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22291 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22292 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22294 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22295 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22297 hr = IDirect3DDevice9_BeginScene(device);
22298 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22299 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
22300 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22301 hr = IDirect3DDevice9_EndScene(device);
22302 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22304 color = getPixelColor(device, 160, 120);
22305 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22306 color = getPixelColor(device, 480, 120);
22307 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22308 color = getPixelColor(device, 160, 360);
22309 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
22310 color = getPixelColor(device, 480, 360);
22311 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
22313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22314 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22316 hr = IDirect3DDevice9_BeginScene(device);
22317 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22318 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
22319 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22320 hr = IDirect3DDevice9_EndScene(device);
22321 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22323 color = getPixelColor(device, 160, 120);
22324 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22325 color = getPixelColor(device, 480, 120);
22326 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22327 color = getPixelColor(device, 160, 360);
22328 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
22329 color = getPixelColor(device, 480, 360);
22330 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
22332 refcount = IDirect3DDevice9_Release(device);
22333 ok(!refcount, "Device has %u references left.\n", refcount);
22334 IDirect3D9_Release(d3d);
22335 DestroyWindow(window);
22338 START_TEST(visual)
22340 D3DADAPTER_IDENTIFIER9 identifier;
22341 IDirect3D9 *d3d;
22342 HRESULT hr;
22344 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
22346 skip("could not create D3D9 object\n");
22347 return;
22350 memset(&identifier, 0, sizeof(identifier));
22351 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
22352 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22353 trace("Driver string: \"%s\"\n", identifier.Driver);
22354 trace("Description string: \"%s\"\n", identifier.Description);
22355 /* Only Windows XP's default VGA driver should have an empty description */
22356 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
22357 trace("Device name string: \"%s\"\n", identifier.DeviceName);
22358 ok(identifier.DeviceName[0], "Empty device name.\n");
22359 trace("Driver version %d.%d.%d.%d\n",
22360 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
22361 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
22363 IDirect3D9_Release(d3d);
22365 test_sanity();
22366 depth_clamp_test();
22367 stretchrect_test();
22368 lighting_test();
22369 test_specular_lighting();
22370 clear_test();
22371 color_fill_test();
22372 fog_test();
22373 test_cube_wrap();
22374 z_range_test();
22375 maxmip_test();
22376 offscreen_test();
22377 ds_size_test();
22378 test_blend();
22379 test_shademode();
22380 srgbtexture_test();
22381 release_buffer_test();
22382 float_texture_test();
22383 g16r16_texture_test();
22384 pixelshader_blending_test();
22385 texture_transform_flags_test();
22386 autogen_mipmap_test();
22387 fixed_function_decl_test();
22388 conditional_np2_repeat_test();
22389 fixed_function_bumpmap_test();
22390 test_pointsize();
22391 tssargtemp_test();
22392 np2_stretch_rect_test();
22393 yuv_color_test();
22394 yuv_layout_test();
22395 zwriteenable_test();
22396 alphatest_test();
22397 viewport_test();
22398 test_constant_clamp_vs();
22399 test_compare_instructions();
22400 test_mova();
22401 loop_index_test();
22402 sincos_test();
22403 sgn_test();
22404 clip_planes_test();
22405 test_vshader_input();
22406 test_vshader_float16();
22407 stream_test();
22408 fog_with_shader_test();
22409 texbem_test();
22410 texdepth_test();
22411 texkill_test();
22412 volume_v16u16_test();
22413 constant_clamp_ps_test();
22414 cnd_test();
22415 dp2add_ps_test();
22416 unbound_sampler_test();
22417 nested_loop_test();
22418 pretransformed_varying_test();
22419 vface_register_test();
22420 test_fragment_coords();
22421 multiple_rendertargets_test();
22422 texop_test();
22423 texop_range_test();
22424 alphareplicate_test();
22425 dp3_alpha_test();
22426 depth_buffer_test();
22427 depth_buffer2_test();
22428 depth_blit_test();
22429 intz_test();
22430 shadow_test();
22431 fp_special_test();
22432 depth_bounds_test();
22433 srgbwrite_format_test();
22434 update_surface_test();
22435 multisample_get_rtdata_test();
22436 zenable_test();
22437 fog_special_test();
22438 volume_srgb_test();
22439 volume_dxt5_test();
22440 add_dirty_rect_test();
22441 multisampled_depth_buffer_test();
22442 resz_test();
22443 stencil_cull_test();
22444 test_per_stage_constant();
22445 test_3dc_formats();
22446 test_fog_interpolation();
22447 test_negative_fixedfunction_fog();
22448 test_position_index();
22449 test_table_fog_zw();
22450 test_signed_formats();
22451 test_multisample_mismatch();
22452 test_texcoordindex();
22453 test_vertex_blending();
22454 test_updatetexture();
22455 test_depthbias();
22456 test_flip();
22457 test_uninitialized_varyings();
22458 test_multisample_init();
22459 test_texture_blending();
22460 test_color_clamping();
22461 test_line_antialiasing_blending();
22462 test_dsy();
22463 test_evict_bound_resources();
22464 test_max_index16();
22465 test_backbuffer_resize();
22466 test_drawindexedprimitiveup();