d3d9/tests: Test the default diffuse color for vertex shaders.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blobc0ed616a5641f584374dc62012332cb133b01a50
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 WNDCLASSA wc = {0};
55 HWND ret;
56 wc.lpfnWndProc = DefWindowProcA;
57 wc.lpszClassName = "d3d9_test_wc";
58 RegisterClassA(&wc);
60 ret = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_SYSMENU | WS_POPUP,
61 0, 0, 640, 480, 0, 0, 0, 0);
62 ShowWindow(ret, SW_SHOW);
63 return ret;
66 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
68 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
69 c1 >>= 8; c2 >>= 8;
70 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
71 c1 >>= 8; c2 >>= 8;
72 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
73 c1 >>= 8; c2 >>= 8;
74 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
75 return TRUE;
78 /* Locks a given surface and returns the color at (x,y). It's the caller's
79 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
80 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
82 DWORD color;
83 HRESULT hr;
84 D3DSURFACE_DESC desc;
85 RECT rectToLock = {x, y, x+1, y+1};
86 D3DLOCKED_RECT lockedRect;
88 hr = IDirect3DSurface9_GetDesc(surface, &desc);
89 if(FAILED(hr)) /* This is not a test */
91 trace("Can't get the surface description, hr=%08x\n", hr);
92 return 0xdeadbeef;
95 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
96 if(FAILED(hr)) /* This is not a test */
98 trace("Can't lock the surface, hr=%08x\n", hr);
99 return 0xdeadbeef;
101 switch(desc.Format) {
102 case D3DFMT_A8R8G8B8:
104 color = ((DWORD *) lockedRect.pBits)[0];
105 break;
107 default:
108 trace("Error: unknown surface format: %d\n", desc.Format);
109 color = 0xdeadbeef;
110 break;
112 hr = IDirect3DSurface9_UnlockRect(surface);
113 if(FAILED(hr))
115 trace("Can't unlock the surface, hr=%08x\n", hr);
117 return color;
120 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
122 DWORD ret;
123 IDirect3DSurface9 *surf = NULL, *target = NULL;
124 HRESULT hr;
125 D3DLOCKED_RECT lockedRect;
126 RECT rectToLock = {x, y, x+1, y+1};
128 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
129 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
130 if (FAILED(hr) || !surf)
132 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
133 return 0xdeadbeef;
136 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
137 if(FAILED(hr))
139 trace("Can't get the render target, hr=%08x\n", hr);
140 ret = 0xdeadbeed;
141 goto out;
144 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
145 if (FAILED(hr))
147 trace("Can't read the render target data, hr=%08x\n", hr);
148 ret = 0xdeadbeec;
149 goto out;
152 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
153 if(FAILED(hr))
155 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
156 ret = 0xdeadbeeb;
157 goto out;
160 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
161 * really important for these tests
163 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
164 hr = IDirect3DSurface9_UnlockRect(surf);
165 if(FAILED(hr))
167 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
170 out:
171 if(target) IDirect3DSurface9_Release(target);
172 if(surf) IDirect3DSurface9_Release(surf);
173 return ret;
176 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
178 D3DPRESENT_PARAMETERS present_parameters = {0};
179 IDirect3DDevice9 *device;
181 present_parameters.Windowed = windowed;
182 present_parameters.hDeviceWindow = device_window;
183 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184 present_parameters.BackBufferWidth = 640;
185 present_parameters.BackBufferHeight = 480;
186 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187 present_parameters.EnableAutoDepthStencil = TRUE;
188 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
191 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
192 return device;
194 return NULL;
197 static void cleanup_device(IDirect3DDevice9 *device)
199 if (device)
201 D3DPRESENT_PARAMETERS present_parameters;
202 IDirect3DSwapChain9 *swapchain;
203 ULONG ref;
205 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
206 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
207 IDirect3DSwapChain9_Release(swapchain);
208 ref = IDirect3DDevice9_Release(device);
209 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
210 DestroyWindow(present_parameters.hDeviceWindow);
214 static void test_sanity(void)
216 IDirect3DDevice9 *device;
217 IDirect3D9 *d3d;
218 D3DCOLOR color;
219 ULONG refcount;
220 HWND window;
221 HRESULT hr;
223 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
224 0, 0, 640, 480, NULL, NULL, NULL, NULL);
225 d3d = Direct3DCreate9(D3D_SDK_VERSION);
226 ok(!!d3d, "Failed to create a D3D object.\n");
227 if (!(device = create_device(d3d, window, window, TRUE)))
229 skip("Failed to create a D3D device, skipping tests.\n");
230 goto done;
233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
234 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
235 color = getPixelColor(device, 1, 1);
236 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
239 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
242 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
243 color = getPixelColor(device, 639, 479);
244 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
246 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
247 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
249 refcount = IDirect3DDevice9_Release(device);
250 ok(!refcount, "Device has %u references left.\n", refcount);
251 done:
252 IDirect3D9_Release(d3d);
253 DestroyWindow(window);
256 static void lighting_test(void)
258 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
259 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
260 IDirect3DDevice9 *device;
261 D3DMATERIAL9 material;
262 IDirect3D9 *d3d;
263 D3DCOLOR color;
264 ULONG refcount;
265 HWND window;
266 HRESULT hr;
267 unsigned int i;
269 static const D3DMATRIX mat =
271 1.0f, 0.0f, 0.0f, 0.0f,
272 0.0f, 1.0f, 0.0f, 0.0f,
273 0.0f, 0.0f, 1.0f, 0.0f,
274 0.0f, 0.0f, 0.0f, 1.0f,
275 }}},
276 mat_singular =
278 1.0f, 0.0f, 1.0f, 0.0f,
279 0.0f, 1.0f, 0.0f, 0.0f,
280 1.0f, 0.0f, 1.0f, 0.0f,
281 0.0f, 0.0f, 0.5f, 1.0f,
282 }}},
283 mat_transf =
285 0.0f, 0.0f, 1.0f, 0.0f,
286 0.0f, 1.0f, 0.0f, 0.0f,
287 -1.0f, 0.0f, 0.0f, 0.0f,
288 10.f, 10.0f, 10.0f, 1.0f,
289 }}},
290 mat_nonaffine =
292 1.0f, 0.0f, 0.0f, 0.0f,
293 0.0f, 1.0f, 0.0f, 0.0f,
294 0.0f, 0.0f, 1.0f, -1.0f,
295 10.f, 10.0f, 10.0f, 0.0f,
296 }}};
297 static const struct
299 struct vec3 position;
300 DWORD diffuse;
302 unlitquad[] =
304 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
305 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
306 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
307 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
309 litquad[] =
311 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
312 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
313 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
314 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
316 lighting_test[] =
318 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
319 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
320 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
321 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
323 static const struct
325 struct vec3 position;
326 struct vec3 normal;
327 DWORD diffuse;
329 unlitnquad[] =
331 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
332 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
333 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
334 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
336 litnquad[] =
338 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
339 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
340 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
341 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
343 nquad[] =
345 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
346 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
347 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
348 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
350 rotatedquad[] =
352 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
353 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
354 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
355 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
357 translatedquad[] =
359 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
360 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
361 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
362 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
364 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
365 static const struct
367 const D3DMATRIX *world_matrix;
368 const void *quad;
369 unsigned int size;
370 DWORD expected;
371 const char *message;
373 tests[] =
375 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
376 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
377 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
378 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
381 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
382 0, 0, 640, 480, NULL, NULL, NULL, NULL);
383 d3d = Direct3DCreate9(D3D_SDK_VERSION);
384 ok(!!d3d, "Failed to create a D3D object.\n");
385 if (!(device = create_device(d3d, window, window, TRUE)))
387 skip("Failed to create a D3D device, skipping tests.\n");
388 goto done;
391 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
392 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
394 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
395 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
396 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
397 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
398 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
399 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
401 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
403 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
404 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
405 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
406 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
409 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
411 hr = IDirect3DDevice9_SetFVF(device, fvf);
412 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
414 hr = IDirect3DDevice9_BeginScene(device);
415 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
417 /* No lights are defined... That means, lit vertices should be entirely black */
418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
419 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
420 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
421 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
422 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
425 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
426 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
427 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
428 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
430 hr = IDirect3DDevice9_SetFVF(device, nfvf);
431 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
433 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
434 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
435 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
436 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
437 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
440 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
441 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
442 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
443 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
445 hr = IDirect3DDevice9_EndScene(device);
446 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
448 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
449 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
450 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
451 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
452 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
453 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
454 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
455 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
457 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
459 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
460 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
462 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
464 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
465 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
468 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
470 hr = IDirect3DDevice9_BeginScene(device);
471 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
473 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
474 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
475 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
477 hr = IDirect3DDevice9_EndScene(device);
478 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
480 color = getPixelColor(device, 320, 240);
481 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
484 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
485 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
486 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
487 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#x.\n", hr);
489 memset(&material, 0, sizeof(material));
490 material.Diffuse.r = 0.0;
491 material.Diffuse.g = 0.0;
492 material.Diffuse.b = 0.0;
493 material.Diffuse.a = 1.0;
494 material.Ambient.r = 0.0;
495 material.Ambient.g = 0.0;
496 material.Ambient.b = 0.0;
497 material.Ambient.a = 0.0;
498 material.Specular.r = 0.0;
499 material.Specular.g = 0.0;
500 material.Specular.b = 0.0;
501 material.Specular.a = 0.0;
502 material.Emissive.r = 0.0;
503 material.Emissive.g = 0.0;
504 material.Emissive.b = 0.0;
505 material.Emissive.a = 0.0;
506 material.Power = 0.0;
507 hr = IDirect3DDevice9_SetMaterial(device, &material);
508 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
511 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
515 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
517 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
518 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
520 hr = IDirect3DDevice9_BeginScene(device);
521 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
523 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
524 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
526 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
528 hr = IDirect3DDevice9_EndScene(device);
529 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
531 color = getPixelColor(device, 320, 240);
532 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
533 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
535 refcount = IDirect3DDevice9_Release(device);
536 ok(!refcount, "Device has %u references left.\n", refcount);
537 done:
538 IDirect3D9_Release(d3d);
539 DestroyWindow(window);
542 static void test_specular_lighting(void)
544 static const unsigned int vertices_side = 5;
545 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
546 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
547 static const D3DMATRIX mat =
549 1.0f, 0.0f, 0.0f, 0.0f,
550 0.0f, 1.0f, 0.0f, 0.0f,
551 0.0f, 0.0f, 1.0f, 0.0f,
552 0.0f, 0.0f, 0.0f, 1.0f,
553 }}};
554 static const D3DLIGHT9 directional =
556 D3DLIGHT_DIRECTIONAL,
557 {0.0f, 0.0f, 0.0f, 0.0f},
558 {1.0f, 1.0f, 1.0f, 0.0f},
559 {0.0f, 0.0f, 0.0f, 0.0f},
560 {0.0f, 0.0f, 0.0f},
561 {0.0f, 0.0f, 1.0f},
563 point =
565 D3DLIGHT_POINT,
566 {0.0f, 0.0f, 0.0f, 0.0f},
567 {1.0f, 1.0f, 1.0f, 0.0f},
568 {0.0f, 0.0f, 0.0f, 0.0f},
569 {0.0f, 0.0f, 0.0f},
570 {0.0f, 0.0f, 0.0f},
571 100.0f,
572 0.0f,
573 0.0f, 0.0f, 1.0f,
575 spot =
577 D3DLIGHT_SPOT,
578 {0.0f, 0.0f, 0.0f, 0.0f},
579 {1.0f, 1.0f, 1.0f, 0.0f},
580 {0.0f, 0.0f, 0.0f, 0.0f},
581 {0.0f, 0.0f, 0.0f},
582 {0.0f, 0.0f, 1.0f},
583 100.0f,
584 1.0f,
585 0.0f, 0.0f, 1.0f,
586 M_PI / 12.0f, M_PI / 3.0f
588 /* The chosen range value makes the test fail when using a manhattan
589 * distance metric vs the correct euclidean distance. */
590 point_range =
592 D3DLIGHT_POINT,
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, 0.0f},
598 1.2f,
599 0.0f,
600 0.0f, 0.0f, 1.0f,
602 static const struct expected_color
604 unsigned int x, y;
605 D3DCOLOR color;
607 expected_directional[] =
609 {160, 120, 0x00ffffff},
610 {320, 120, 0x00ffffff},
611 {480, 120, 0x00ffffff},
612 {160, 240, 0x00ffffff},
613 {320, 240, 0x00ffffff},
614 {480, 240, 0x00ffffff},
615 {160, 360, 0x00ffffff},
616 {320, 360, 0x00ffffff},
617 {480, 360, 0x00ffffff},
619 expected_directional_local[] =
621 {160, 120, 0x003c3c3c},
622 {320, 120, 0x00717171},
623 {480, 120, 0x003c3c3c},
624 {160, 240, 0x00717171},
625 {320, 240, 0x00ffffff},
626 {480, 240, 0x00717171},
627 {160, 360, 0x003c3c3c},
628 {320, 360, 0x00717171},
629 {480, 360, 0x003c3c3c},
631 expected_point[] =
633 {160, 120, 0x00282828},
634 {320, 120, 0x005a5a5a},
635 {480, 120, 0x00282828},
636 {160, 240, 0x005a5a5a},
637 {320, 240, 0x00ffffff},
638 {480, 240, 0x005a5a5a},
639 {160, 360, 0x00282828},
640 {320, 360, 0x005a5a5a},
641 {480, 360, 0x00282828},
643 expected_point_local[] =
645 {160, 120, 0x00000000},
646 {320, 120, 0x00070707},
647 {480, 120, 0x00000000},
648 {160, 240, 0x00070707},
649 {320, 240, 0x00ffffff},
650 {480, 240, 0x00070707},
651 {160, 360, 0x00000000},
652 {320, 360, 0x00070707},
653 {480, 360, 0x00000000},
655 expected_spot[] =
657 {160, 120, 0x00000000},
658 {320, 120, 0x00141414},
659 {480, 120, 0x00000000},
660 {160, 240, 0x00141414},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00141414},
663 {160, 360, 0x00000000},
664 {320, 360, 0x00141414},
665 {480, 360, 0x00000000},
667 expected_spot_local[] =
669 {160, 120, 0x00000000},
670 {320, 120, 0x00020202},
671 {480, 120, 0x00000000},
672 {160, 240, 0x00020202},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x00020202},
675 {160, 360, 0x00000000},
676 {320, 360, 0x00020202},
677 {480, 360, 0x00000000},
679 expected_point_range[] =
681 {160, 120, 0x00000000},
682 {320, 120, 0x005a5a5a},
683 {480, 120, 0x00000000},
684 {160, 240, 0x005a5a5a},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x005a5a5a},
687 {160, 360, 0x00000000},
688 {320, 360, 0x005a5a5a},
689 {480, 360, 0x00000000},
691 static const struct
693 const D3DLIGHT9 *light;
694 BOOL local_viewer;
695 const struct expected_color *expected;
696 unsigned int expected_count;
698 tests[] =
700 {&directional, FALSE, expected_directional,
701 sizeof(expected_directional) / sizeof(expected_directional[0])},
702 {&directional, TRUE, expected_directional_local,
703 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
704 {&point, FALSE, expected_point,
705 sizeof(expected_point) / sizeof(expected_point[0])},
706 {&point, TRUE, expected_point_local,
707 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
708 {&spot, FALSE, expected_spot,
709 sizeof(expected_spot) / sizeof(expected_spot[0])},
710 {&spot, TRUE, expected_spot_local,
711 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
712 {&point_range, FALSE, expected_point_range,
713 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
715 IDirect3DDevice9 *device;
716 D3DMATERIAL9 material;
717 IDirect3D9 *d3d;
718 D3DCOLOR color;
719 ULONG refcount;
720 HWND window;
721 HRESULT hr;
722 unsigned int i, j, x, y;
723 struct
725 struct vec3 position;
726 struct vec3 normal;
727 } *quad;
728 WORD *indices;
730 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
731 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
732 for (i = 0, y = 0; y < vertices_side; ++y)
734 for (x = 0; x < vertices_side; ++x)
736 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
737 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
738 quad[i].position.z = 1.0f;
739 quad[i].normal.x = 0.0f;
740 quad[i].normal.y = 0.0f;
741 quad[i++].normal.z = -1.0f;
744 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
746 for (x = 0; x < (vertices_side - 1); ++x)
748 indices[i++] = y * vertices_side + x + 1;
749 indices[i++] = y * vertices_side + x;
750 indices[i++] = (y + 1) * vertices_side + x;
751 indices[i++] = y * vertices_side + x + 1;
752 indices[i++] = (y + 1) * vertices_side + x;
753 indices[i++] = (y + 1) * vertices_side + x + 1;
757 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
758 0, 0, 640, 480, NULL, NULL, NULL, NULL);
759 d3d = Direct3DCreate9(D3D_SDK_VERSION);
760 ok(!!d3d, "Failed to create a D3D object.\n");
761 if (!(device = create_device(d3d, window, window, TRUE)))
763 skip("Failed to create a D3D device, skipping tests.\n");
764 goto done;
767 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
768 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
769 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
770 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
771 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
772 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
774 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
775 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
776 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
778 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
780 hr = IDirect3DDevice9_SetFVF(device, fvf);
781 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
783 memset(&material, 0, sizeof(material));
784 material.Specular.r = 1.0f;
785 material.Specular.g = 1.0f;
786 material.Specular.b = 1.0f;
787 material.Specular.a = 1.0f;
788 material.Power = 30.0f;
789 hr = IDirect3DDevice9_SetMaterial(device, &material);
790 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
792 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
793 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
795 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
797 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
799 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
800 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
803 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
805 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
806 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
808 hr = IDirect3DDevice9_BeginScene(device);
809 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
811 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
812 0, vertices_side * vertices_side, indices_count / 3, indices,
813 D3DFMT_INDEX16, quad, sizeof(quad[0]));
814 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
816 hr = IDirect3DDevice9_EndScene(device);
817 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
819 for (j = 0; j < tests[i].expected_count; ++j)
821 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
822 ok(color_match(color, tests[i].expected[j].color, 1),
823 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
824 tests[i].expected[j].color, tests[i].expected[j].x,
825 tests[i].expected[j].y, color, i);
829 refcount = IDirect3DDevice9_Release(device);
830 ok(!refcount, "Device has %u references left.\n", refcount);
831 done:
832 IDirect3D9_Release(d3d);
833 DestroyWindow(window);
834 HeapFree(GetProcessHeap(), 0, indices);
835 HeapFree(GetProcessHeap(), 0, quad);
838 static void clear_test(void)
840 /* Tests the correctness of clearing parameters */
841 HRESULT hr;
842 D3DRECT rect[2];
843 D3DRECT rect_negneg;
844 DWORD color;
845 D3DVIEWPORT9 old_vp, vp;
846 RECT scissor;
847 DWORD oldColorWrite;
848 BOOL invalid_clear_failed = FALSE;
849 IDirect3DDevice9 *device;
850 IDirect3D9 *d3d;
851 ULONG refcount;
852 HWND window;
854 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
855 0, 0, 640, 480, NULL, NULL, NULL, NULL);
856 d3d = Direct3DCreate9(D3D_SDK_VERSION);
857 ok(!!d3d, "Failed to create a D3D object.\n");
858 if (!(device = create_device(d3d, window, window, TRUE)))
860 skip("Failed to create a D3D device, skipping tests.\n");
861 goto done;
864 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
865 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
867 /* Positive x, negative y */
868 rect[0].x1 = 0;
869 rect[0].y1 = 480;
870 rect[0].x2 = 320;
871 rect[0].y2 = 240;
873 /* Positive x, positive y */
874 rect[1].x1 = 0;
875 rect[1].y1 = 0;
876 rect[1].x2 = 320;
877 rect[1].y2 = 240;
878 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
879 * returns D3D_OK, but ignores the rectangle silently
881 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
882 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
883 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
885 /* negative x, negative y */
886 rect_negneg.x1 = 640;
887 rect_negneg.y1 = 240;
888 rect_negneg.x2 = 320;
889 rect_negneg.y2 = 0;
890 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
891 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
892 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
894 color = getPixelColor(device, 160, 360); /* lower left quad */
895 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
896 color = getPixelColor(device, 160, 120); /* upper left quad */
897 if(invalid_clear_failed) {
898 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
899 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
900 } else {
901 /* If the negative rectangle was dropped silently, the correct ones are cleared */
902 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
904 color = getPixelColor(device, 480, 360); /* lower right quad */
905 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
906 color = getPixelColor(device, 480, 120); /* upper right quad */
907 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
909 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
911 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
912 * clear the red quad in the top left part of the render target. For some reason it
913 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
914 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
915 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
916 * pick some obvious value
918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
921 /* Test how the viewport affects clears */
922 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
923 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
924 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
925 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
927 vp.X = 160;
928 vp.Y = 120;
929 vp.Width = 160;
930 vp.Height = 120;
931 vp.MinZ = 0.0;
932 vp.MaxZ = 1.0;
933 hr = IDirect3DDevice9_SetViewport(device, &vp);
934 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
936 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
938 vp.X = 320;
939 vp.Y = 240;
940 vp.Width = 320;
941 vp.Height = 240;
942 vp.MinZ = 0.0;
943 vp.MaxZ = 1.0;
944 hr = IDirect3DDevice9_SetViewport(device, &vp);
945 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
946 rect[0].x1 = 160;
947 rect[0].y1 = 120;
948 rect[0].x2 = 480;
949 rect[0].y2 = 360;
950 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
951 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
953 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
954 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
956 color = getPixelColor(device, 158, 118);
957 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
958 color = getPixelColor(device, 162, 118);
959 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
960 color = getPixelColor(device, 158, 122);
961 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
962 color = getPixelColor(device, 162, 122);
963 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
965 color = getPixelColor(device, 318, 238);
966 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
967 color = getPixelColor(device, 322, 238);
968 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
969 color = getPixelColor(device, 318, 242);
970 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
971 color = getPixelColor(device, 322, 242);
972 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
974 color = getPixelColor(device, 478, 358);
975 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
976 color = getPixelColor(device, 482, 358);
977 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
978 color = getPixelColor(device, 478, 362);
979 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
980 color = getPixelColor(device, 482, 362);
981 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
983 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
985 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
986 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
988 scissor.left = 160;
989 scissor.right = 480;
990 scissor.top = 120;
991 scissor.bottom = 360;
992 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
993 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
995 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
998 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
999 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1002 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1003 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1005 color = getPixelColor(device, 158, 118);
1006 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1007 color = getPixelColor(device, 162, 118);
1008 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1009 color = getPixelColor(device, 158, 122);
1010 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1011 color = getPixelColor(device, 162, 122);
1012 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1014 color = getPixelColor(device, 158, 358);
1015 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1016 color = getPixelColor(device, 162, 358);
1017 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1018 color = getPixelColor(device, 158, 358);
1019 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1020 color = getPixelColor(device, 162, 362);
1021 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1023 color = getPixelColor(device, 478, 118);
1024 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1025 color = getPixelColor(device, 478, 122);
1026 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1027 color = getPixelColor(device, 482, 122);
1028 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1029 color = getPixelColor(device, 482, 358);
1030 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1032 color = getPixelColor(device, 478, 358);
1033 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1034 color = getPixelColor(device, 478, 362);
1035 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1036 color = getPixelColor(device, 482, 358);
1037 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1038 color = getPixelColor(device, 482, 362);
1039 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1041 color = getPixelColor(device, 318, 238);
1042 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1043 color = getPixelColor(device, 318, 242);
1044 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1045 color = getPixelColor(device, 322, 238);
1046 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1047 color = getPixelColor(device, 322, 242);
1048 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1050 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1052 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1053 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1055 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1057 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1058 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1059 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1061 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1062 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1065 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1067 /* Colorwriteenable does not affect the clear */
1068 color = getPixelColor(device, 320, 240);
1069 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1071 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1073 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1074 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1076 rect[0].x1 = 0;
1077 rect[0].y1 = 0;
1078 rect[0].x2 = 640;
1079 rect[0].y2 = 480;
1080 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1081 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1083 color = getPixelColor(device, 320, 240);
1084 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1085 "Clear with count = 0, rect != NULL has color %08x\n", color);
1087 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1090 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1091 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1092 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1094 color = getPixelColor(device, 320, 240);
1095 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1096 "Clear with count = 1, rect = NULL has color %08x\n", color);
1098 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1100 refcount = IDirect3DDevice9_Release(device);
1101 ok(!refcount, "Device has %u references left.\n", refcount);
1102 done:
1103 IDirect3D9_Release(d3d);
1104 DestroyWindow(window);
1107 static void color_fill_test(void)
1109 IDirect3DSurface9 *surface;
1110 IDirect3DTexture9 *texture;
1111 D3DCOLOR fill_color, color;
1112 DWORD fill_a, expected_a;
1113 IDirect3DDevice9 *device;
1114 IDirect3D9 *d3d;
1115 ULONG refcount;
1116 HWND window;
1117 HRESULT hr;
1118 static const struct
1120 D3DPOOL pool;
1121 DWORD usage;
1122 HRESULT hr;
1124 resource_types[] =
1126 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1127 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1128 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1129 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1130 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1131 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1133 static const struct
1135 D3DFORMAT format;
1136 const char *name;
1137 enum
1139 CHECK_FILL_VALUE = 0x1,
1140 TODO_FILL_RETURN = 0x2,
1141 BLOCKS = 0x4,
1142 } flags;
1143 DWORD fill_value;
1145 formats[] =
1147 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1148 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1149 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1150 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1151 /* Real hardware reliably fills the surface with the blue channel but
1152 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1153 * channel. Don't bother checking the result because P8 surfaces are
1154 * essentially useless in d3d9. */
1155 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1156 /* Windows drivers produce different results for these formats.
1157 * No driver produces a YUV value that matches the input RGB
1158 * value, and no driver produces a proper DXT compression block.
1160 * Even the clear value 0 does not reliably produce a fill value
1161 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1163 * The YUV tests are disabled because they produce a driver-dependent
1164 * result on Wine.
1165 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1166 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1167 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0},
1168 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1169 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1170 * when created as texture. */
1172 unsigned int i;
1173 D3DLOCKED_RECT locked_rect;
1174 DWORD *surface_data;
1175 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1177 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1178 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1179 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1180 ok(!!d3d, "Failed to create a D3D object.\n");
1181 if (!(device = create_device(d3d, window, window, TRUE)))
1183 skip("Failed to create a D3D device, skipping tests.\n");
1184 goto done;
1187 /* Test ColorFill on a the backbuffer (should pass) */
1188 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1189 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1191 fill_color = 0x112233;
1192 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1193 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1195 color = getPixelColor(device, 0, 0);
1196 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1198 IDirect3DSurface9_Release(surface);
1200 /* Test ColorFill on a render target surface (should pass) */
1201 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1202 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1203 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1205 fill_color = 0x445566;
1206 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1207 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1209 color = getPixelColorFromSurface(surface, 0, 0);
1210 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1212 IDirect3DSurface9_Release(surface);
1214 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1215 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1216 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1217 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1219 fill_color = 0x778899;
1220 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1221 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1223 color = getPixelColorFromSurface(surface, 0, 0);
1224 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1226 IDirect3DSurface9_Release(surface);
1228 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1229 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1230 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1231 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1233 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1234 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1236 IDirect3DSurface9_Release(surface);
1238 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1239 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1240 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1242 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1243 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1245 IDirect3DSurface9_Release(surface);
1247 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1249 texture = NULL;
1250 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1251 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1252 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1253 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1254 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1256 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1257 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1258 hr, resource_types[i].hr, i);
1260 IDirect3DSurface9_Release(surface);
1261 IDirect3DTexture9_Release(texture);
1264 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1266 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1267 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1269 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1270 continue;
1273 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1274 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1275 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1277 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1278 if (formats[i].flags & TODO_FILL_RETURN)
1279 todo_wine ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1280 else
1281 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1283 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1284 if (formats[i].flags & TODO_FILL_RETURN)
1285 todo_wine ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1286 else
1287 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1289 if (SUCCEEDED(hr))
1291 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1292 if (formats[i].flags & BLOCKS)
1293 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1294 else
1295 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1298 if (formats[i].flags & CHECK_FILL_VALUE)
1300 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1301 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1302 surface_data = locked_rect.pBits;
1303 fill_a = (surface_data[0] & 0xff000000) >> 24;
1304 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1305 /* Windows drivers disagree on how to promote the 8 bit per channel
1306 * input argument to 16 bit for D3DFMT_G16R16. */
1307 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1308 abs((expected_a) - (fill_a)) < 3,
1309 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1310 formats[i].fill_value, surface_data[0], formats[i].name);
1311 hr = IDirect3DSurface9_UnlockRect(surface);
1312 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1315 IDirect3DSurface9_Release(surface);
1318 refcount = IDirect3DDevice9_Release(device);
1319 ok(!refcount, "Device has %u references left.\n", refcount);
1320 done:
1321 IDirect3D9_Release(d3d);
1322 DestroyWindow(window);
1326 * c7 mova ARGB mov ARGB
1327 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1328 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1329 * -0.4 0 0x0000ffff -1 0x0000ff00
1330 * 0.4 0 0x0000ffff 0 0x0000ffff
1331 * 1.6 2 0x00ff00ff 1 0x000000ff
1332 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1334 static void test_mova(void)
1336 IDirect3DVertexDeclaration9 *vertex_declaration;
1337 IDirect3DVertexShader9 *mova_shader;
1338 IDirect3DVertexShader9 *mov_shader;
1339 IDirect3DDevice9 *device;
1340 unsigned int i, j;
1341 IDirect3D9 *d3d;
1342 ULONG refcount;
1343 D3DCAPS9 caps;
1344 HWND window;
1345 HRESULT hr;
1347 static const DWORD mova_test[] =
1349 0xfffe0200, /* vs_2_0 */
1350 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1351 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1352 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1353 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1354 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1355 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1356 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1357 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1358 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1359 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1360 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1361 0x0000ffff /* END */
1363 static const DWORD mov_test[] =
1365 0xfffe0101, /* vs_1_1 */
1366 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1367 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1368 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1369 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1370 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1371 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1372 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1373 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1374 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1375 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1376 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1377 0x0000ffff /* END */
1379 static const struct
1381 float in[4];
1382 DWORD out;
1384 test_data[2][6] =
1387 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1388 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1389 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1390 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1391 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1392 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1395 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1396 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1397 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1398 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1399 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1400 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1403 static const struct vec3 quad[] =
1405 {-1.0f, -1.0f, 0.0f},
1406 {-1.0f, 1.0f, 0.0f},
1407 { 1.0f, -1.0f, 0.0f},
1408 { 1.0f, 1.0f, 0.0f},
1410 static const D3DVERTEXELEMENT9 decl_elements[] =
1412 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1413 D3DDECL_END()
1416 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1417 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1418 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1419 ok(!!d3d, "Failed to create a D3D object.\n");
1420 if (!(device = create_device(d3d, window, window, TRUE)))
1422 skip("Failed to create a D3D device, skipping tests.\n");
1423 goto done;
1426 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1427 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1428 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1430 skip("No vs_2_0 support, skipping tests.\n");
1431 IDirect3DDevice9_Release(device);
1432 goto done;
1435 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1436 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1437 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1438 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1439 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1440 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1441 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1442 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1444 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1445 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1446 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1448 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1450 DWORD color;
1452 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1453 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1455 hr = IDirect3DDevice9_BeginScene(device);
1456 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1459 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1461 hr = IDirect3DDevice9_EndScene(device);
1462 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1464 color = getPixelColor(device, 320, 240);
1465 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1466 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1469 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1471 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1472 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1474 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1475 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1478 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1479 IDirect3DVertexShader9_Release(mova_shader);
1480 IDirect3DVertexShader9_Release(mov_shader);
1481 refcount = IDirect3DDevice9_Release(device);
1482 ok(!refcount, "Device has %u references left.\n", refcount);
1483 done:
1484 IDirect3D9_Release(d3d);
1485 DestroyWindow(window);
1488 static void fog_test(void)
1490 float start = 0.0f, end = 1.0f;
1491 IDirect3DDevice9 *device;
1492 IDirect3D9 *d3d;
1493 D3DCOLOR color;
1494 ULONG refcount;
1495 D3DCAPS9 caps;
1496 HWND window;
1497 HRESULT hr;
1498 int i;
1500 /* Gets full z based fog with linear fog, no fog with specular color. */
1501 static const struct
1503 float x, y, z;
1504 D3DCOLOR diffuse;
1505 D3DCOLOR specular;
1507 untransformed_1[] =
1509 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1510 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1511 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1512 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1514 /* Ok, I am too lazy to deal with transform matrices. */
1515 untransformed_2[] =
1517 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1518 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1519 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1520 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1522 untransformed_3[] =
1524 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1525 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1526 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1527 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1529 far_quad1[] =
1531 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1532 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1533 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1534 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1536 far_quad2[] =
1538 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1539 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1540 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1541 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1543 /* Untransformed ones. Give them a different diffuse color to make the
1544 * test look nicer. It also makes making sure that they are drawn
1545 * correctly easier. */
1546 static const struct
1548 float x, y, z, rhw;
1549 D3DCOLOR diffuse;
1550 D3DCOLOR specular;
1552 transformed_1[] =
1554 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1555 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1556 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1557 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1559 transformed_2[] =
1561 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1562 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1563 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1564 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1566 static const struct
1568 struct vec3 position;
1569 DWORD diffuse;
1571 rev_fog_quads[] =
1573 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1574 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1575 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1576 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1578 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1579 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1580 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1581 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1583 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1584 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1585 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1586 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1588 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1589 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1590 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1591 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1593 static const D3DMATRIX ident_mat =
1595 1.0f, 0.0f, 0.0f, 0.0f,
1596 0.0f, 1.0f, 0.0f, 0.0f,
1597 0.0f, 0.0f, 1.0f, 0.0f,
1598 0.0f, 0.0f, 0.0f, 1.0f
1599 }}};
1600 static const D3DMATRIX world_mat1 =
1602 1.0f, 0.0f, 0.0f, 0.0f,
1603 0.0f, 1.0f, 0.0f, 0.0f,
1604 0.0f, 0.0f, 1.0f, 0.0f,
1605 0.0f, 0.0f, -0.5f, 1.0f
1606 }}};
1607 static const D3DMATRIX world_mat2 =
1609 1.0f, 0.0f, 0.0f, 0.0f,
1610 0.0f, 1.0f, 0.0f, 0.0f,
1611 0.0f, 0.0f, 1.0f, 0.0f,
1612 0.0f, 0.0f, 1.0f, 1.0f
1613 }}};
1614 static const D3DMATRIX proj_mat =
1616 1.0f, 0.0f, 0.0f, 0.0f,
1617 0.0f, 1.0f, 0.0f, 0.0f,
1618 0.0f, 0.0f, 1.0f, 0.0f,
1619 0.0f, 0.0f, -1.0f, 1.0f
1620 }}};
1621 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1622 static const WORD Indices2[] =
1624 0, 1, 2, 2, 3, 0,
1625 4, 5, 6, 6, 7, 4,
1626 8, 9, 10, 10, 11, 8,
1627 12, 13, 14, 14, 15, 12,
1630 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1631 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1632 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1633 ok(!!d3d, "Failed to create a D3D object.\n");
1634 if (!(device = create_device(d3d, window, window, TRUE)))
1636 skip("Failed to create a D3D device, skipping tests.\n");
1637 goto done;
1640 memset(&caps, 0, sizeof(caps));
1641 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1642 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1644 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1646 /* Setup initial states: No lighting, fog on, fog color */
1647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1648 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1650 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1652 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1654 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1655 /* Some of the tests seem to depend on the projection matrix explicitly
1656 * being set to an identity matrix, even though that's the default.
1657 * (AMD Radeon HD 6310, Windows 7) */
1658 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1659 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1661 /* First test: Both table fog and vertex fog off */
1662 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1663 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1664 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1665 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1667 /* Start = 0, end = 1. Should be default, but set them */
1668 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1669 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1671 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1673 hr = IDirect3DDevice9_BeginScene(device);
1674 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1676 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1677 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1679 /* Untransformed, vertex fog = NONE, table fog = NONE:
1680 * Read the fog weighting from the specular color. */
1681 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1682 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1683 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1685 /* That makes it use the Z value */
1686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1687 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1688 /* Untransformed, vertex fog != none (or table fog != none):
1689 * Use the Z value as input into the equation. */
1690 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1691 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1692 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1694 /* transformed verts */
1695 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1696 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1697 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1698 * Use specular color alpha component. */
1699 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1700 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1701 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1703 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1704 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1705 /* Transformed, table fog != none, vertex anything:
1706 * Use Z value as input to the fog equation. */
1707 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1708 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1709 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1711 hr = IDirect3DDevice9_EndScene(device);
1712 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1714 color = getPixelColor(device, 160, 360);
1715 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1716 color = getPixelColor(device, 160, 120);
1717 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1718 color = getPixelColor(device, 480, 120);
1719 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1720 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1722 color = getPixelColor(device, 480, 360);
1723 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1725 else
1727 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1728 * The settings above result in no fogging with vertex fog
1730 color = getPixelColor(device, 480, 120);
1731 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1732 trace("Info: Table fog not supported by this device\n");
1734 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1736 /* Now test the special case fogstart == fogend */
1737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1738 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1740 hr = IDirect3DDevice9_BeginScene(device);
1741 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1743 start = 512;
1744 end = 512;
1745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1746 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1748 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1750 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1751 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1753 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1755 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1757 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1758 * Would result in a completely fog-free primitive because start > zcoord,
1759 * but because start == end, the primitive is fully covered by fog. The
1760 * same happens to the 2nd untransformed quad with z = 1.0. The third
1761 * transformed quad remains unfogged because the fogcoords are read from
1762 * the specular color and has fixed fogstart and fogend. */
1763 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1764 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1765 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1766 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1767 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1768 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1770 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1771 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1772 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1773 * Use specular color alpha component. */
1774 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1775 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1776 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1778 hr = IDirect3DDevice9_EndScene(device);
1779 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1781 color = getPixelColor(device, 160, 360);
1782 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1783 color = getPixelColor(device, 160, 120);
1784 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1785 color = getPixelColor(device, 480, 120);
1786 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1787 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1789 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1790 * but without shaders it seems to work everywhere
1792 end = 0.2;
1793 start = 0.8;
1794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1795 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1797 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1798 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1799 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1801 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1802 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1803 * so skip this for now
1805 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1806 const char *mode = (i ? "table" : "vertex");
1807 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1808 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1810 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1812 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1813 hr = IDirect3DDevice9_BeginScene(device);
1814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1815 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1816 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1817 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1818 hr = IDirect3DDevice9_EndScene(device);
1819 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1821 color = getPixelColor(device, 160, 360);
1822 ok(color_match(color, 0x0000ff00, 1),
1823 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1825 color = getPixelColor(device, 160, 120);
1826 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1827 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1829 color = getPixelColor(device, 480, 120);
1830 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1831 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1833 color = getPixelColor(device, 480, 360);
1834 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1836 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1838 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1839 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1840 break;
1844 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1846 /* A simple fog + non-identity world matrix test */
1847 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1848 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1850 start = 0.0;
1851 end = 1.0;
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1853 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1855 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1857 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1859 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1861 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1862 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1864 hr = IDirect3DDevice9_BeginScene(device);
1865 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1867 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1868 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1870 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1871 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1872 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1873 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1874 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1875 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1877 hr = IDirect3DDevice9_EndScene(device);
1878 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1880 color = getPixelColor(device, 160, 360);
1881 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1882 "Unfogged quad has color %08x\n", color);
1883 color = getPixelColor(device, 160, 120);
1884 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1885 "Fogged out quad has color %08x\n", color);
1887 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1889 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1890 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1891 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1892 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1893 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1895 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1896 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1898 hr = IDirect3DDevice9_BeginScene(device);
1899 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1901 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1902 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1904 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1905 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1906 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1907 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1908 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1909 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1911 hr = IDirect3DDevice9_EndScene(device);
1912 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1914 color = getPixelColor(device, 160, 360);
1915 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1916 color = getPixelColor(device, 160, 120);
1917 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1918 "Fogged out quad has color %08x\n", color);
1920 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1922 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
1923 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1924 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1925 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1927 else
1929 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1932 /* Test RANGEFOG vs FOGTABLEMODE */
1933 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1934 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1937 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1938 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1939 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1942 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1944 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
1945 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
1946 * Note that the fog coordinate is interpolated linearly across the vertices,
1947 * so the different eye distance at the screen center should not matter. */
1948 start = 0.75f;
1949 end = 0.75001f;
1950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1951 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1953 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1955 /* Table fog: Range fog is not used */
1956 hr = IDirect3DDevice9_BeginScene(device);
1957 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1960 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
1962 untransformed_3, sizeof(*untransformed_3));
1963 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1965 hr = IDirect3DDevice9_EndScene(device);
1966 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1968 color = getPixelColor(device, 10, 10);
1969 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1970 color = getPixelColor(device, 630, 10);
1971 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1972 color = getPixelColor(device, 10, 470);
1973 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1974 color = getPixelColor(device, 630, 470);
1975 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1978 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1980 /* Vertex fog: Rangefog is used */
1981 hr = IDirect3DDevice9_BeginScene(device);
1982 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1985 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1987 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
1989 untransformed_3, sizeof(*untransformed_3));
1990 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1992 hr = IDirect3DDevice9_EndScene(device);
1993 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1995 color = getPixelColor(device, 10, 10);
1996 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1997 "Rangefog with vertex fog returned color 0x%08x\n", color);
1998 color = getPixelColor(device, 630, 10);
1999 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2000 "Rangefog with vertex fog returned color 0x%08x\n", color);
2001 color = getPixelColor(device, 10, 470);
2002 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2003 "Rangefog with vertex fog returned color 0x%08x\n", color);
2004 color = getPixelColor(device, 630, 470);
2005 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2006 "Rangefog with vertex fog returned color 0x%08x\n", color);
2008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2009 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2012 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2014 else
2016 skip("Range fog or table fog not supported, skipping range fog tests\n");
2019 refcount = IDirect3DDevice9_Release(device);
2020 ok(!refcount, "Device has %u references left.\n", refcount);
2021 done:
2022 IDirect3D9_Release(d3d);
2023 DestroyWindow(window);
2026 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2027 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2028 * regardless of the actual addressing mode set. The way this test works is
2029 * that we sample in one of the corners of the cubemap with filtering enabled,
2030 * and check the interpolated color. There are essentially two reasonable
2031 * things an implementation can do: Either pick one of the faces and
2032 * interpolate the edge texel with itself (i.e., clamp within the face), or
2033 * interpolate between the edge texels of the three involved faces. It should
2034 * never involve the border color or the other side (texcoord wrapping) of a
2035 * face in the interpolation. */
2036 static void test_cube_wrap(void)
2038 IDirect3DVertexDeclaration9 *vertex_declaration;
2039 IDirect3DSurface9 *face_surface, *surface;
2040 IDirect3DCubeTexture9 *texture;
2041 D3DLOCKED_RECT locked_rect;
2042 IDirect3DDevice9 *device;
2043 unsigned int x, y, face;
2044 IDirect3D9 *d3d;
2045 ULONG refcount;
2046 D3DCAPS9 caps;
2047 HWND window;
2048 HRESULT hr;
2050 static const float quad[][6] =
2052 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2053 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2054 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2055 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2057 static const D3DVERTEXELEMENT9 decl_elements[] =
2059 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2060 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2061 D3DDECL_END()
2063 static const struct
2065 D3DTEXTUREADDRESS mode;
2066 const char *name;
2068 address_modes[] =
2070 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2071 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2072 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2073 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2074 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2077 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2078 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2079 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2080 ok(!!d3d, "Failed to create a D3D object.\n");
2081 if (!(device = create_device(d3d, window, window, TRUE)))
2083 skip("Failed to create a D3D device, skipping tests.\n");
2084 goto done;
2087 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2088 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2089 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2091 skip("No cube texture support, skipping tests.\n");
2092 IDirect3DDevice9_Release(device);
2093 goto done;
2096 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2097 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2098 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2099 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2101 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2102 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2103 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2105 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2106 D3DPOOL_DEFAULT, &texture, NULL);
2107 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2109 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2110 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2112 for (y = 0; y < 128; ++y)
2114 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2115 for (x = 0; x < 64; ++x)
2117 *ptr++ = 0xff0000ff;
2119 for (x = 64; x < 128; ++x)
2121 *ptr++ = 0xffff0000;
2125 hr = IDirect3DSurface9_UnlockRect(surface);
2126 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2128 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2129 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2131 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2132 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2134 IDirect3DSurface9_Release(face_surface);
2136 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2137 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2139 for (y = 0; y < 128; ++y)
2141 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2142 for (x = 0; x < 64; ++x)
2144 *ptr++ = 0xffff0000;
2146 for (x = 64; x < 128; ++x)
2148 *ptr++ = 0xff0000ff;
2152 hr = IDirect3DSurface9_UnlockRect(surface);
2153 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2155 /* Create cube faces */
2156 for (face = 1; face < 6; ++face)
2158 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2159 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2161 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2162 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2164 IDirect3DSurface9_Release(face_surface);
2167 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2168 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2170 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2171 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2172 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2173 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2174 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2175 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2178 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2180 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2182 DWORD color;
2184 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2185 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2187 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2189 hr = IDirect3DDevice9_BeginScene(device);
2190 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2192 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2193 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2195 hr = IDirect3DDevice9_EndScene(device);
2196 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2198 color = getPixelColor(device, 320, 240);
2199 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2200 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2201 color, address_modes[x].name);
2203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2204 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2206 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2207 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2210 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2211 IDirect3DCubeTexture9_Release(texture);
2212 IDirect3DSurface9_Release(surface);
2213 refcount = IDirect3DDevice9_Release(device);
2214 ok(!refcount, "Device has %u references left.\n", refcount);
2215 done:
2216 IDirect3D9_Release(d3d);
2217 DestroyWindow(window);
2220 static void offscreen_test(void)
2222 IDirect3DSurface9 *backbuffer, *offscreen;
2223 IDirect3DTexture9 *offscreenTexture;
2224 IDirect3DDevice9 *device;
2225 IDirect3D9 *d3d;
2226 D3DCOLOR color;
2227 ULONG refcount;
2228 HWND window;
2229 HRESULT hr;
2231 static const float quad[][5] =
2233 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2234 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2235 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2236 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2239 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2240 0, 0, 640, 480, NULL, NULL, NULL, NULL);
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_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2250 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2252 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2253 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2254 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2255 if (!offscreenTexture)
2257 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2258 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2259 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2260 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2261 if (!offscreenTexture)
2263 skip("Cannot create an offscreen render target.\n");
2264 IDirect3DDevice9_Release(device);
2265 goto done;
2269 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2270 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2272 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2273 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2275 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2276 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2278 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2279 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2280 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2281 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2282 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2283 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2284 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2285 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2289 hr = IDirect3DDevice9_BeginScene(device);
2290 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2292 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2293 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2294 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2295 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2297 /* Draw without textures - Should result in a white quad. */
2298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2301 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2302 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2303 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2304 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2306 /* This time with the texture. */
2307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2308 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2310 hr = IDirect3DDevice9_EndScene(device);
2311 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2313 /* Center quad - should be white */
2314 color = getPixelColor(device, 320, 240);
2315 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2316 /* Some quad in the cleared part of the texture */
2317 color = getPixelColor(device, 170, 240);
2318 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2319 /* Part of the originally cleared back buffer */
2320 color = getPixelColor(device, 10, 10);
2321 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2322 color = getPixelColor(device, 10, 470);
2323 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2325 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2327 IDirect3DSurface9_Release(backbuffer);
2328 IDirect3DTexture9_Release(offscreenTexture);
2329 IDirect3DSurface9_Release(offscreen);
2330 refcount = IDirect3DDevice9_Release(device);
2331 ok(!refcount, "Device has %u references left.\n", refcount);
2332 done:
2333 IDirect3D9_Release(d3d);
2334 DestroyWindow(window);
2337 /* This test tests fog in combination with shaders.
2338 * What's tested: linear fog (vertex and table) with pixel shader
2339 * linear table fog with non foggy vertex shader
2340 * vertex fog with foggy vertex shader, non-linear
2341 * fog with shader, non-linear fog with foggy shader,
2342 * linear table fog with foggy shader */
2343 static void fog_with_shader_test(void)
2345 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2346 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2347 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2348 IDirect3DDevice9 *device;
2349 unsigned int i, j;
2350 IDirect3D9 *d3d;
2351 ULONG refcount;
2352 D3DCAPS9 caps;
2353 DWORD color;
2354 HWND window;
2355 HRESULT hr;
2356 union
2358 float f;
2359 DWORD i;
2360 } start, end;
2362 /* basic vertex shader without fog computation ("non foggy") */
2363 static const DWORD vertex_shader_code1[] =
2365 0xfffe0101, /* vs_1_1 */
2366 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2367 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2368 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2369 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2370 0x0000ffff
2372 /* basic vertex shader with reversed fog computation ("foggy") */
2373 static const DWORD vertex_shader_code2[] =
2375 0xfffe0101, /* vs_1_1 */
2376 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2377 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2378 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2379 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2380 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2381 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2382 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2383 0x0000ffff
2385 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2386 static const DWORD vertex_shader_code3[] =
2388 0xfffe0200, /* vs_2_0 */
2389 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2390 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2391 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2392 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2393 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2394 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2395 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2396 0x0000ffff
2398 /* basic pixel shader */
2399 static const DWORD pixel_shader_code[] =
2401 0xffff0101, /* ps_1_1 */
2402 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2403 0x0000ffff
2405 static const DWORD pixel_shader_code2[] =
2407 0xffff0200, /* ps_2_0 */
2408 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2409 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2410 0x0000ffff
2412 struct
2414 struct vec3 position;
2415 DWORD diffuse;
2417 quad[] =
2419 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2420 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2421 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2422 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2424 static const D3DVERTEXELEMENT9 decl_elements[] =
2426 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2427 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2428 D3DDECL_END()
2430 /* This reference data was collected on a nVidia GeForce 7600GS driver
2431 * version 84.19 DirectX version 9.0c on Windows XP. */
2432 static const struct test_data_t
2434 int vshader;
2435 int pshader;
2436 D3DFOGMODE vfog;
2437 D3DFOGMODE tfog;
2438 unsigned int color[11];
2440 test_data[] =
2442 /* only pixel shader: */
2443 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2444 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2445 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2446 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2447 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2448 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2449 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2450 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2451 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2452 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2453 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2454 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2455 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2456 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2457 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2459 /* vertex shader */
2460 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2461 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2462 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2463 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2464 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2465 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2466 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2467 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2468 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2470 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2471 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2472 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2473 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2474 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2475 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2477 /* vertex shader and pixel shader */
2478 /* The next 4 tests would read the fog coord output, but it isn't available.
2479 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2480 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2481 * These tests should be disabled if some other hardware behaves differently
2483 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2484 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2485 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2486 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2487 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2488 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2489 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2490 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2491 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2492 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2493 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2494 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2496 /* These use the Z coordinate with linear table fog */
2497 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2498 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2499 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2500 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2501 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2502 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2503 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2504 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2505 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2506 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2507 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2508 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2510 /* Non-linear table fog without fog coord */
2511 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2512 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2513 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2514 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2515 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2516 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2518 /* These tests fail on older Nvidia drivers */
2519 /* foggy vertex shader */
2520 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2521 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2522 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2523 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2524 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2525 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2526 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2527 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2528 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2529 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2530 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2531 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2533 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2534 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2535 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2536 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2537 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2538 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2539 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2540 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2541 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2542 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2543 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2544 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2546 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2547 * all using the fixed fog-coord linear fog
2549 /* vs_1_1 with ps_1_1 */
2550 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2551 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2552 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2553 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2554 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2555 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2556 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2557 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2558 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2559 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2560 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2561 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2563 /* vs_2_0 with ps_1_1 */
2564 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2565 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2566 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2567 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2568 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2569 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2570 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2571 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2572 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2573 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2574 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2575 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2577 /* vs_1_1 with ps_2_0 */
2578 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2579 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2580 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2581 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2582 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2583 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2584 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2585 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2586 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2587 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2588 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2589 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2591 /* vs_2_0 with ps_2_0 */
2592 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2593 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2594 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2595 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2596 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2597 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2598 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2599 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2600 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2601 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2602 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2603 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2605 /* These use table fog. Here the shader-provided fog coordinate is
2606 * ignored and the z coordinate used instead
2608 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2609 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2610 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2611 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2612 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2613 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2614 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2615 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2616 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2618 static const D3DMATRIX identity =
2620 1.0f, 0.0f, 0.0f, 0.0f,
2621 0.0f, 1.0f, 0.0f, 0.0f,
2622 0.0f, 0.0f, 1.0f, 0.0f,
2623 0.0f, 0.0f, 0.0f, 1.0f,
2624 }}};
2626 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2627 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2628 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2629 ok(!!d3d, "Failed to create a D3D object.\n");
2630 if (!(device = create_device(d3d, window, window, TRUE)))
2632 skip("Failed to create a D3D device, skipping tests.\n");
2633 goto done;
2636 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2637 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2638 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2640 skip("No shader model 2 support, skipping tests.\n");
2641 IDirect3DDevice9_Release(device);
2642 goto done;
2645 /* NOTE: Changing these values will not affect the tests with foggy vertex
2646 * shader, as the values are hardcoded in the shader. */
2647 start.f = 0.1f;
2648 end.f = 0.9f;
2650 /* Some of the tests seem to depend on the projection matrix explicitly
2651 * being set to an identity matrix, even though that's the default.
2652 * (AMD Radeon HD 6310, Windows 7) */
2653 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2654 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2656 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2657 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2658 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2659 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2660 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2661 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2662 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2663 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2664 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2665 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2666 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2667 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2669 /* Setup initial states: No lighting, fog on, fog color */
2670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2671 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2673 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2675 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2676 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2677 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2680 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2681 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2682 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2684 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2685 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2686 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2688 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2690 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2692 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2693 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2694 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2695 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2697 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2699 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2701 for(j=0; j < 11; j++)
2703 /* Don't use the whole zrange to prevent rounding errors */
2704 quad[0].position.z = 0.001f + (float)j / 10.02f;
2705 quad[1].position.z = 0.001f + (float)j / 10.02f;
2706 quad[2].position.z = 0.001f + (float)j / 10.02f;
2707 quad[3].position.z = 0.001f + (float)j / 10.02f;
2709 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2710 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2712 hr = IDirect3DDevice9_BeginScene(device);
2713 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2716 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2718 hr = IDirect3DDevice9_EndScene(device);
2719 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2721 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2722 color = getPixelColor(device, 128, 240);
2723 ok(color_match(color, test_data[i].color[j], 13),
2724 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2725 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2728 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2730 IDirect3DVertexShader9_Release(vertex_shader[1]);
2731 IDirect3DVertexShader9_Release(vertex_shader[2]);
2732 IDirect3DVertexShader9_Release(vertex_shader[3]);
2733 IDirect3DPixelShader9_Release(pixel_shader[1]);
2734 IDirect3DPixelShader9_Release(pixel_shader[2]);
2735 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2736 refcount = IDirect3DDevice9_Release(device);
2737 ok(!refcount, "Device has %u references left.\n", refcount);
2738 done:
2739 IDirect3D9_Release(d3d);
2740 DestroyWindow(window);
2743 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2744 unsigned int i, x, y;
2745 HRESULT hr;
2746 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2747 D3DLOCKED_RECT locked_rect;
2749 /* Generate the textures */
2750 for(i=0; i<2; i++)
2752 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2753 D3DPOOL_MANAGED, &texture[i], NULL);
2754 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2756 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2757 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2758 for (y = 0; y < 128; ++y)
2760 if(i)
2761 { /* Set up black texture with 2x2 texel white spot in the middle */
2762 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2763 for (x = 0; x < 128; ++x)
2765 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2768 else
2769 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2770 * (if multiplied with bumpenvmat)
2772 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2773 for (x = 0; x < 128; ++x)
2775 if(abs(x-64)>abs(y-64))
2777 if(x < 64)
2778 *ptr++ = 0xc000;
2779 else
2780 *ptr++ = 0x4000;
2782 else
2784 if(y < 64)
2785 *ptr++ = 0x0040;
2786 else
2787 *ptr++ = 0x00c0;
2792 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2793 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2795 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2796 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2798 /* Disable texture filtering */
2799 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2800 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2801 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2802 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2804 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2805 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2806 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2807 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2811 /* Test the behavior of the texbem instruction with normal 2D and projective
2812 * 2D textures. */
2813 static void texbem_test(void)
2815 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2816 /* Use asymmetric matrix to test loading. */
2817 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2818 IDirect3DPixelShader9 *pixel_shader = NULL;
2819 IDirect3DTexture9 *texture1, *texture2;
2820 IDirect3DTexture9 *texture = NULL;
2821 D3DLOCKED_RECT locked_rect;
2822 IDirect3DDevice9 *device;
2823 IDirect3D9 *d3d;
2824 ULONG refcount;
2825 D3DCAPS9 caps;
2826 DWORD color;
2827 HWND window;
2828 HRESULT hr;
2829 int i;
2831 static const DWORD pixel_shader_code[] =
2833 0xffff0101, /* ps_1_1*/
2834 0x00000042, 0xb00f0000, /* tex t0*/
2835 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2836 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2837 0x0000ffff
2839 static const DWORD double_texbem_code[] =
2841 0xffff0103, /* ps_1_3 */
2842 0x00000042, 0xb00f0000, /* tex t0 */
2843 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2844 0x00000042, 0xb00f0002, /* tex t2 */
2845 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2846 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2847 0x0000ffff /* end */
2849 static const float quad[][7] =
2851 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2852 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2853 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2854 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2856 static const float quad_proj[][9] =
2858 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2859 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2860 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2861 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2863 static const float double_quad[] =
2865 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2866 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2867 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2868 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2870 static const D3DVERTEXELEMENT9 decl_elements[][4] =
2873 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2874 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2875 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2876 D3DDECL_END()
2879 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2880 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2881 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2882 D3DDECL_END()
2886 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2887 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2888 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2889 ok(!!d3d, "Failed to create a D3D object.\n");
2890 if (!(device = create_device(d3d, window, window, TRUE)))
2892 skip("Failed to create a D3D device, skipping tests.\n");
2893 goto done;
2896 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2897 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2898 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2900 skip("No ps_1_1 support, skipping tests.\n");
2901 IDirect3DDevice9_Release(device);
2902 goto done;
2905 generate_bumpmap_textures(device);
2907 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2908 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2909 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2910 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2911 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2913 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2914 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2916 for(i=0; i<2; i++)
2918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2921 if(i)
2923 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2924 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2927 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2928 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2929 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2930 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2932 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2933 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2934 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2935 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2937 hr = IDirect3DDevice9_BeginScene(device);
2938 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2940 if(!i)
2941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2942 else
2943 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2944 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2946 hr = IDirect3DDevice9_EndScene(device);
2947 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2949 /* The Window 8 testbot (WARP) seems to use the transposed
2950 * D3DTSS_BUMPENVMAT matrix. */
2951 color = getPixelColor(device, 160, 240);
2952 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
2953 "Got unexpected color 0x%08x.\n", color);
2954 color = getPixelColor(device, 480, 240);
2955 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
2956 "Got unexpected color 0x%08x.\n", color);
2957 color = getPixelColor(device, 320, 120);
2958 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
2959 "Got unexpected color 0x%08x.\n", color);
2960 color = getPixelColor(device, 320, 360);
2961 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
2962 "Got unexpected color 0x%08x.\n", color);
2964 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2965 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2967 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2968 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2969 IDirect3DPixelShader9_Release(pixel_shader);
2971 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2972 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2973 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2976 /* clean up */
2977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2978 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2980 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2981 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2983 for(i=0; i<2; i++)
2985 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2986 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2987 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2988 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2989 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2990 IDirect3DTexture9_Release(texture);
2993 /* Test double texbem */
2994 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2995 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2996 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2997 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2998 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2999 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3000 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3001 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3003 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3004 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3005 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3006 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3008 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3009 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3011 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3012 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3013 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3014 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3015 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3016 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3019 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3020 #define tex 0x00ff0000
3021 #define tex1 0x0000ff00
3022 #define origin 0x000000ff
3023 static const DWORD pixel_data[] = {
3024 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3025 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3026 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3027 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3028 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3029 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3030 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3031 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3033 #undef tex1
3034 #undef tex2
3035 #undef origin
3037 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3038 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3039 for(i = 0; i < 8; i++) {
3040 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3042 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3043 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3046 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3047 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3048 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3049 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3050 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3051 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3052 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3053 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3054 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3055 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3056 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3057 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3059 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3060 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3061 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3062 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3063 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3065 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3067 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3070 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3071 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3072 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3073 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3074 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3075 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3076 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3077 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3078 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3079 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3081 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3082 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3083 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3084 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3085 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3086 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3087 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3088 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3089 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3090 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3091 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3092 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3093 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3094 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3095 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3096 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3098 hr = IDirect3DDevice9_BeginScene(device);
3099 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3101 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3102 hr = IDirect3DDevice9_EndScene(device);
3103 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3104 /* The Window 8 testbot (WARP) seems to use the transposed
3105 * D3DTSS_BUMPENVMAT matrix. */
3106 color = getPixelColor(device, 320, 240);
3107 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3108 "Got unexpected color 0x%08x.\n", color);
3110 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3111 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3113 IDirect3DPixelShader9_Release(pixel_shader);
3114 IDirect3DTexture9_Release(texture);
3115 IDirect3DTexture9_Release(texture1);
3116 IDirect3DTexture9_Release(texture2);
3117 refcount = IDirect3DDevice9_Release(device);
3118 ok(!refcount, "Device has %u references left.\n", refcount);
3119 done:
3120 IDirect3D9_Release(d3d);
3121 DestroyWindow(window);
3124 static void z_range_test(void)
3126 IDirect3DVertexShader9 *shader;
3127 IDirect3DDevice9 *device;
3128 IDirect3D9 *d3d;
3129 ULONG refcount;
3130 D3DCAPS9 caps;
3131 DWORD color;
3132 HWND window;
3133 HRESULT hr;
3135 static const struct
3137 struct vec3 position;
3138 DWORD diffuse;
3140 quad[] =
3142 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3143 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3144 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3145 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3147 quad2[] =
3149 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3150 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3151 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3152 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3154 static const struct
3156 struct vec4 position;
3157 DWORD diffuse;
3159 quad3[] =
3161 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3162 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3163 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3164 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3166 quad4[] =
3168 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3169 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3170 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3171 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3173 static const DWORD shader_code[] =
3175 0xfffe0101, /* vs_1_1 */
3176 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3177 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3178 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3179 0x0000ffff /* end */
3181 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3182 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3184 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3185 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3186 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3187 ok(!!d3d, "Failed to create a D3D object.\n");
3188 if (!(device = create_device(d3d, window, window, TRUE)))
3190 skip("Failed to create a D3D device, skipping tests.\n");
3191 goto done;
3194 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3195 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3197 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3198 * then call Present. Then clear the color buffer to make sure it has some defined content
3199 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3200 * by the depth value. */
3201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3202 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3204 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3205 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3206 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3209 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3211 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3213 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3215 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3217 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3218 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3219 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3221 hr = IDirect3DDevice9_BeginScene(device);
3222 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3224 /* Test the untransformed vertex path */
3225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3226 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3228 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3230 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3232 /* Test the transformed vertex path */
3233 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3234 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3237 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3239 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3241 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3243 hr = IDirect3DDevice9_EndScene(device);
3244 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3246 /* Do not test the exact corner pixels, but go pretty close to them */
3248 /* Clipped because z > 1.0 */
3249 color = getPixelColor(device, 28, 238);
3250 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3251 color = getPixelColor(device, 28, 241);
3252 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3253 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3254 else
3255 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3257 /* Not clipped, > z buffer clear value(0.75).
3259 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3260 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3261 * equal to a stored depth buffer value of 0.5. */
3262 color = getPixelColor(device, 31, 238);
3263 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3264 color = getPixelColor(device, 31, 241);
3265 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3266 color = getPixelColor(device, 100, 238);
3267 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3268 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3269 color = getPixelColor(device, 100, 241);
3270 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3271 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3273 /* Not clipped, < z buffer clear value */
3274 color = getPixelColor(device, 104, 238);
3275 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3276 color = getPixelColor(device, 104, 241);
3277 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3278 color = getPixelColor(device, 318, 238);
3279 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3280 color = getPixelColor(device, 318, 241);
3281 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3283 /* Clipped because z < 0.0 */
3284 color = getPixelColor(device, 321, 238);
3285 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3286 color = getPixelColor(device, 321, 241);
3287 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3288 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3289 else
3290 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3292 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3293 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3295 /* Test the shader path */
3296 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3298 skip("Vertex shaders not supported, skipping tests.\n");
3299 IDirect3DDevice9_Release(device);
3300 goto done;
3302 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3303 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3305 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3306 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3308 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3309 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3310 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3311 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3313 hr = IDirect3DDevice9_BeginScene(device);
3314 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3316 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3317 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3318 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3319 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3322 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3323 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3324 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3326 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3328 hr = IDirect3DDevice9_EndScene(device);
3329 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3331 IDirect3DVertexShader9_Release(shader);
3333 /* Z < 1.0 */
3334 color = getPixelColor(device, 28, 238);
3335 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3337 /* 1.0 < z < 0.75 */
3338 color = getPixelColor(device, 31, 238);
3339 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3340 color = getPixelColor(device, 100, 238);
3341 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3342 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3344 /* 0.75 < z < 0.0 */
3345 color = getPixelColor(device, 104, 238);
3346 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3347 color = getPixelColor(device, 318, 238);
3348 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3350 /* 0.0 < z */
3351 color = getPixelColor(device, 321, 238);
3352 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3354 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3355 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3357 refcount = IDirect3DDevice9_Release(device);
3358 ok(!refcount, "Device has %u references left.\n", refcount);
3359 done:
3360 IDirect3D9_Release(d3d);
3361 DestroyWindow(window);
3364 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3366 D3DSURFACE_DESC desc;
3367 D3DLOCKED_RECT l;
3368 HRESULT hr;
3369 unsigned int x, y;
3370 DWORD *mem;
3372 memset(&desc, 0, sizeof(desc));
3373 memset(&l, 0, sizeof(l));
3374 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3375 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3376 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3377 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3378 if(FAILED(hr)) return;
3380 for(y = 0; y < desc.Height; y++)
3382 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3383 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3385 mem[x] = color;
3388 hr = IDirect3DSurface9_UnlockRect(surface);
3389 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3392 static void stretchrect_test(void)
3394 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3395 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3396 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3397 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3398 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3399 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3400 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3401 IDirect3DSurface9 *backbuffer;
3402 IDirect3DDevice9 *device;
3403 IDirect3D9 *d3d;
3404 D3DCOLOR color;
3405 ULONG refcount;
3406 HWND window;
3407 HRESULT hr;
3409 static const RECT src_rect = {0, 0, 640, 480};
3410 static const RECT src_rect_flipy = {0, 480, 640, 0};
3411 static const RECT dst_rect = {0, 0, 640, 480};
3412 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3413 static const RECT src_rect64 = {0, 0, 64, 64};
3414 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3415 static const RECT dst_rect64 = {0, 0, 64, 64};
3416 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3418 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3419 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3420 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3421 ok(!!d3d, "Failed to create a D3D object.\n");
3422 if (!(device = create_device(d3d, window, window, TRUE)))
3424 skip("Failed to create a D3D device, skipping tests.\n");
3425 goto done;
3428 /* Create our temporary surfaces in system memory. */
3429 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3430 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3431 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3432 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3433 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3434 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3436 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3437 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3438 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3439 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3440 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3441 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3442 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3443 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3444 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3445 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3447 /* Create render target surfaces. */
3448 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3449 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3450 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3451 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3452 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3453 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3454 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3455 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3456 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3457 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3458 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3460 /* Create render target textures. */
3461 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3462 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3463 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3464 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3465 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3466 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3467 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3468 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3469 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3470 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3471 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3472 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3473 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3474 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3475 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3476 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3477 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3478 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3479 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3480 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3482 /* Create regular textures in D3DPOOL_DEFAULT. */
3483 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3484 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3485 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3486 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3487 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3488 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3489 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3490 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3491 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3492 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3493 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3494 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3496 /**********************************************************************
3497 * Tests for when the source parameter is an offscreen plain surface. *
3498 **********************************************************************/
3500 /* Fill the offscreen 64x64 surface with green. */
3501 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3503 /* offscreenplain ==> offscreenplain, same size. */
3504 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3505 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3506 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3507 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3508 /* Blit without scaling. */
3509 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3510 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3511 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3512 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3513 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3514 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3515 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3516 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3517 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3518 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3519 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3521 /* offscreenplain ==> rendertarget texture, same size. */
3522 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3523 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3524 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3525 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3526 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3527 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3528 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3529 /* Blit without scaling. */
3530 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3531 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3532 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3533 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3534 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3535 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3536 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3537 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3538 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3539 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3540 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3542 /* offscreenplain ==> rendertarget surface, same size. */
3543 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3544 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3545 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3546 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3547 /* Blit without scaling. */
3548 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3549 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3550 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3551 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3552 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3553 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3554 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3555 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3556 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3557 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3558 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3560 /* offscreenplain ==> texture, same size (should fail). */
3561 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3562 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3564 /* Fill the smaller offscreen surface with red. */
3565 fill_surface(surf_offscreen32, 0xffff0000, 0);
3567 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3568 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3569 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3571 /* offscreenplain ==> rendertarget texture, scaling. */
3572 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3573 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3574 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3575 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3576 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3577 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3578 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3580 /* offscreenplain ==> rendertarget surface, scaling. */
3581 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3582 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3583 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3584 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3586 /* offscreenplain ==> texture, scaling (should fail). */
3587 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3588 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3590 /*************************************************************
3591 * Tests for when the source parameter is a regular texture. *
3592 *************************************************************/
3594 /* Fill the surface of the regular texture with blue. */
3595 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3596 fill_surface(surf_temp64, 0xff0000ff, 0);
3597 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3598 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3600 /* texture ==> offscreenplain, same size. */
3601 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3602 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3604 /* texture ==> rendertarget texture, same size. */
3605 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3606 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3607 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3608 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3609 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3610 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3611 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3612 /* Blit without scaling. */
3613 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3614 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3615 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3616 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3617 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3618 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3619 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3620 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3621 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3622 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3623 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3625 /* texture ==> rendertarget surface, same size. */
3626 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3627 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3628 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3629 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3630 /* Blit without scaling. */
3631 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3632 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3633 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3634 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3635 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3636 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3637 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3638 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3639 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3640 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3641 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3643 /* texture ==> texture, same size (should fail). */
3644 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3645 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3647 /* Fill the surface of the smaller regular texture with red. */
3648 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3649 fill_surface(surf_temp32, 0xffff0000, 0);
3650 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3651 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3653 /* texture ==> offscreenplain, scaling (should fail). */
3654 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3655 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3657 /* texture ==> rendertarget texture, scaling. */
3658 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3659 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3660 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3661 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3662 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3663 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3664 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3666 /* texture ==> rendertarget surface, scaling. */
3667 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3668 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3669 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3670 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3672 /* texture ==> texture, scaling (should fail). */
3673 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3674 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3676 /******************************************************************
3677 * Tests for when the source parameter is a rendertarget texture. *
3678 ******************************************************************/
3680 /* Fill the surface of the rendertarget texture with white. */
3681 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3682 fill_surface(surf_temp64, 0xffffffff, 0);
3683 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3684 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3686 /* rendertarget texture ==> offscreenplain, same size. */
3687 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3688 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3690 /* rendertarget texture ==> rendertarget texture, same size. */
3691 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3692 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3693 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3694 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3695 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3696 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3697 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3698 /* Blit without scaling. */
3699 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3700 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3701 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3702 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3703 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3704 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3705 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3706 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3707 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3708 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3709 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3711 /* rendertarget texture ==> rendertarget surface, same size. */
3712 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3713 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3714 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3715 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3716 /* Blit without scaling. */
3717 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3718 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3719 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3720 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3721 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3722 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3723 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3724 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3725 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3726 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3727 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3729 /* rendertarget texture ==> texture, same size (should fail). */
3730 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3731 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3733 /* Fill the surface of the smaller rendertarget texture with red. */
3734 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3735 fill_surface(surf_temp32, 0xffff0000, 0);
3736 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3737 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3739 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3740 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3741 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3743 /* rendertarget texture ==> rendertarget texture, scaling. */
3744 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3745 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3746 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3747 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3748 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3749 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3750 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3752 /* rendertarget texture ==> rendertarget surface, scaling. */
3753 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3754 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3755 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3756 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3758 /* rendertarget texture ==> texture, scaling (should fail). */
3759 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3760 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3762 /******************************************************************
3763 * Tests for when the source parameter is a rendertarget surface. *
3764 ******************************************************************/
3766 /* Fill the surface of the rendertarget surface with black. */
3767 fill_surface(surf_rt64, 0xff000000, 0);
3769 /* rendertarget texture ==> offscreenplain, same size. */
3770 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3771 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3773 /* rendertarget surface ==> rendertarget texture, same size. */
3774 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3775 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3776 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3777 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3778 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3779 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3780 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3781 /* Blit without scaling. */
3782 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3783 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3784 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3785 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3786 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3787 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3788 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3789 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3790 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3791 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3792 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3794 /* rendertarget surface ==> rendertarget surface, same size. */
3795 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3796 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3797 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3798 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3799 /* Blit without scaling. */
3800 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3801 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3802 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3803 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3804 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3805 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3806 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3807 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3808 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3809 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3810 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3812 /* rendertarget surface ==> texture, same size (should fail). */
3813 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3814 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3816 /* Fill the surface of the smaller rendertarget texture with red. */
3817 fill_surface(surf_rt32, 0xffff0000, 0);
3819 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3820 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3821 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3823 /* rendertarget surface ==> rendertarget texture, scaling. */
3824 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3825 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3826 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3827 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3828 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3829 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3830 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3832 /* rendertarget surface ==> rendertarget surface, scaling. */
3833 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3834 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3835 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3836 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3838 /* rendertarget surface ==> texture, scaling (should fail). */
3839 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3840 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3842 /* backbuffer ==> surface tests (no scaling). */
3843 /* Blit with NULL rectangles. */
3844 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
3845 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3846 /* Blit without scaling. */
3847 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
3848 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
3849 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3850 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3851 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
3852 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
3853 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3854 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3855 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
3856 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
3857 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3859 /* TODO: Test format conversions. */
3861 IDirect3DSurface9_Release(backbuffer);
3862 IDirect3DSurface9_Release(surf_rt32);
3863 IDirect3DSurface9_Release(surf_rt64);
3864 IDirect3DSurface9_Release(surf_rt_dest64);
3865 IDirect3DSurface9_Release(surf_temp32);
3866 IDirect3DSurface9_Release(surf_temp64);
3867 IDirect3DSurface9_Release(surf_offscreen32);
3868 IDirect3DSurface9_Release(surf_offscreen64);
3869 IDirect3DSurface9_Release(surf_offscreen_dest64);
3870 IDirect3DSurface9_Release(surf_tex_rt32);
3871 IDirect3DTexture9_Release(tex_rt32);
3872 IDirect3DSurface9_Release(surf_tex_rt64);
3873 IDirect3DTexture9_Release(tex_rt64);
3874 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3875 IDirect3DTexture9_Release(tex_rt_dest64);
3876 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3877 IDirect3DTexture9_Release(tex_rt_dest640_480);
3878 IDirect3DSurface9_Release(surf_tex32);
3879 IDirect3DTexture9_Release(tex32);
3880 IDirect3DSurface9_Release(surf_tex64);
3881 IDirect3DTexture9_Release(tex64);
3882 IDirect3DSurface9_Release(surf_tex_dest64);
3883 IDirect3DTexture9_Release(tex_dest64);
3884 refcount = IDirect3DDevice9_Release(device);
3885 ok(!refcount, "Device has %u references left.\n", refcount);
3886 done:
3887 IDirect3D9_Release(d3d);
3888 DestroyWindow(window);
3891 static void maxmip_test(void)
3893 IDirect3DTexture9 *texture;
3894 IDirect3DSurface9 *surface;
3895 IDirect3DDevice9 *device;
3896 IDirect3D9 *d3d;
3897 D3DCOLOR color;
3898 ULONG refcount;
3899 D3DCAPS9 caps;
3900 HWND window;
3901 HRESULT hr;
3902 DWORD ret;
3904 static const struct
3906 struct
3908 float x, y, z;
3909 float s, t;
3911 v[4];
3913 quads[] =
3916 {-1.0, -1.0, 0.0, 0.0, 0.0},
3917 {-1.0, 0.0, 0.0, 0.0, 1.0},
3918 { 0.0, -1.0, 0.0, 1.0, 0.0},
3919 { 0.0, 0.0, 0.0, 1.0, 1.0},
3922 { 0.0, -1.0, 0.0, 0.0, 0.0},
3923 { 0.0, 0.0, 0.0, 0.0, 1.0},
3924 { 1.0, -1.0, 0.0, 1.0, 0.0},
3925 { 1.0, 0.0, 0.0, 1.0, 1.0},
3928 { 0.0, 0.0, 0.0, 0.0, 0.0},
3929 { 0.0, 1.0, 0.0, 0.0, 1.0},
3930 { 1.0, 0.0, 0.0, 1.0, 0.0},
3931 { 1.0, 1.0, 0.0, 1.0, 1.0},
3934 {-1.0, 0.0, 0.0, 0.0, 0.0},
3935 {-1.0, 1.0, 0.0, 0.0, 1.0},
3936 { 0.0, 0.0, 0.0, 1.0, 0.0},
3937 { 0.0, 1.0, 0.0, 1.0, 1.0},
3941 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3942 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3943 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3944 ok(!!d3d, "Failed to create a D3D object.\n");
3945 if (!(device = create_device(d3d, window, window, TRUE)))
3947 skip("Failed to create a D3D device, skipping tests.\n");
3948 goto done;
3951 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3952 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3953 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
3955 skip("No mipmap support, skipping tests.\n");
3956 IDirect3DDevice9_Release(device);
3957 goto done;
3960 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
3961 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
3962 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3964 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3965 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3966 fill_surface(surface, 0xffff0000, 0);
3967 IDirect3DSurface9_Release(surface);
3968 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3969 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3970 fill_surface(surface, 0xff00ff00, 0);
3971 IDirect3DSurface9_Release(surface);
3972 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3973 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3974 fill_surface(surface, 0xff0000ff, 0);
3975 IDirect3DSurface9_Release(surface);
3977 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3978 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3980 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3983 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3984 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3985 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3987 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3988 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3990 hr = IDirect3DDevice9_BeginScene(device);
3991 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3993 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3994 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3996 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3998 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3999 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4003 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4004 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4005 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4006 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4008 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4009 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4010 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4011 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4013 hr = IDirect3DDevice9_EndScene(device);
4014 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4016 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4017 color = getPixelColor(device, 160, 360);
4018 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4019 color = getPixelColor(device, 480, 360);
4020 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4021 color = getPixelColor(device, 480, 120);
4022 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4023 color = getPixelColor(device, 160, 120);
4024 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4025 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4026 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4028 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4029 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4034 hr = IDirect3DDevice9_BeginScene(device);
4035 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4037 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4038 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4042 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4043 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4045 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4047 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4048 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4050 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4052 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4053 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4055 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4057 hr = IDirect3DDevice9_EndScene(device);
4058 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4060 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4061 * level 3 (> levels in texture) samples from the highest level in the
4062 * texture (level 2). */
4063 color = getPixelColor(device, 160, 360);
4064 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4065 color = getPixelColor(device, 480, 360);
4066 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4067 color = getPixelColor(device, 480, 120);
4068 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4069 color = getPixelColor(device, 160, 120);
4070 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4072 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4074 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4075 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4077 hr = IDirect3DDevice9_BeginScene(device);
4078 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4080 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4081 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4082 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4083 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4084 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4085 ret = IDirect3DTexture9_SetLOD(texture, 1);
4086 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4088 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4090 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4091 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4092 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4093 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4094 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4095 ret = IDirect3DTexture9_SetLOD(texture, 2);
4096 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4097 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4098 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4100 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4101 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4102 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4103 ret = IDirect3DTexture9_SetLOD(texture, 1);
4104 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4106 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4108 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4109 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4110 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4111 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4112 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4113 ret = IDirect3DTexture9_SetLOD(texture, 1);
4114 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4115 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4116 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4118 hr = IDirect3DDevice9_EndScene(device);
4119 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4121 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4122 * level 3 (> levels in texture) samples from the highest level in the
4123 * texture (level 2). */
4124 color = getPixelColor(device, 160, 360);
4125 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4126 color = getPixelColor(device, 480, 360);
4127 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4128 color = getPixelColor(device, 480, 120);
4129 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4130 color = getPixelColor(device, 160, 120);
4131 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4133 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4134 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4136 IDirect3DTexture9_Release(texture);
4137 refcount = IDirect3DDevice9_Release(device);
4138 ok(!refcount, "Device has %u references left.\n", refcount);
4139 done:
4140 IDirect3D9_Release(d3d);
4141 DestroyWindow(window);
4144 static void release_buffer_test(void)
4146 IDirect3DVertexBuffer9 *vb;
4147 IDirect3DIndexBuffer9 *ib;
4148 IDirect3DDevice9 *device;
4149 IDirect3D9 *d3d;
4150 D3DCOLOR color;
4151 ULONG refcount;
4152 HWND window;
4153 HRESULT hr;
4154 BYTE *data;
4155 LONG ref;
4157 static const short indices[] = {3, 4, 5};
4158 static const struct
4160 struct vec3 position;
4161 DWORD diffuse;
4163 quad[] =
4165 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4166 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4167 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4169 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4170 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4171 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4174 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4175 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4176 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4177 ok(!!d3d, "Failed to create a D3D object.\n");
4178 if (!(device = create_device(d3d, window, window, TRUE)))
4180 skip("Failed to create a D3D device, skipping tests.\n");
4181 goto done;
4184 /* Index and vertex buffers should always be creatable */
4185 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4186 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4187 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4188 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4189 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4190 memcpy(data, quad, sizeof(quad));
4191 hr = IDirect3DVertexBuffer9_Unlock(vb);
4192 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4194 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4195 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4196 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4197 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4198 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4199 memcpy(data, indices, sizeof(indices));
4200 hr = IDirect3DIndexBuffer9_Unlock(ib);
4201 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4203 hr = IDirect3DDevice9_SetIndices(device, ib);
4204 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4205 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4206 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4207 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4208 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4210 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4212 /* Now destroy the bound index buffer and draw again */
4213 ref = IDirect3DIndexBuffer9_Release(ib);
4214 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4216 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4217 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4219 hr = IDirect3DDevice9_BeginScene(device);
4220 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4221 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4222 * D3D from making assumptions about the indices or vertices. */
4223 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4224 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4225 hr = IDirect3DDevice9_EndScene(device);
4226 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4228 color = getPixelColor(device, 160, 120);
4229 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4230 color = getPixelColor(device, 480, 360);
4231 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4233 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4234 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4236 /* Index buffer was already destroyed as part of the test */
4237 IDirect3DVertexBuffer9_Release(vb);
4238 refcount = IDirect3DDevice9_Release(device);
4239 ok(!refcount, "Device has %u references left.\n", refcount);
4240 done:
4241 IDirect3D9_Release(d3d);
4242 DestroyWindow(window);
4245 static void float_texture_test(void)
4247 IDirect3DTexture9 *texture;
4248 IDirect3DDevice9 *device;
4249 D3DLOCKED_RECT lr;
4250 IDirect3D9 *d3d;
4251 ULONG refcount;
4252 float *data;
4253 DWORD color;
4254 HWND window;
4255 HRESULT hr;
4257 static const float quad[] =
4259 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4260 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4261 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4262 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4265 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4266 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4267 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4268 ok(!!d3d, "Failed to create a D3D object.\n");
4269 if (!(device = create_device(d3d, window, window, TRUE)))
4271 skip("Failed to create a D3D device, skipping tests.\n");
4272 goto done;
4275 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4276 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4278 skip("D3DFMT_R32F textures not supported\n");
4279 IDirect3DDevice9_Release(device);
4280 goto done;
4283 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4284 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4286 memset(&lr, 0, sizeof(lr));
4287 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4288 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4289 data = lr.pBits;
4290 *data = 0.0;
4291 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4292 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4295 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4296 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4297 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4300 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4302 hr = IDirect3DDevice9_BeginScene(device);
4303 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4304 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4305 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4308 hr = IDirect3DDevice9_EndScene(device);
4309 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4311 color = getPixelColor(device, 240, 320);
4312 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4315 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4317 IDirect3DTexture9_Release(texture);
4318 refcount = IDirect3DDevice9_Release(device);
4319 ok(!refcount, "Device has %u references left.\n", refcount);
4320 done:
4321 IDirect3D9_Release(d3d);
4322 DestroyWindow(window);
4325 static void g16r16_texture_test(void)
4327 IDirect3DTexture9 *texture;
4328 IDirect3DDevice9 *device;
4329 D3DLOCKED_RECT lr;
4330 IDirect3D9 *d3d;
4331 ULONG refcount;
4332 DWORD *data;
4333 DWORD color;
4334 HWND window;
4335 HRESULT hr;
4337 static const float quad[] =
4339 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4340 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4341 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4342 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4345 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4346 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4348 ok(!!d3d, "Failed to create a D3D object.\n");
4349 if (!(device = create_device(d3d, window, window, TRUE)))
4351 skip("Failed to create a D3D device, skipping tests.\n");
4352 goto done;
4355 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4356 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4358 skip("D3DFMT_G16R16 textures not supported\n");
4359 IDirect3DDevice9_Release(device);
4360 goto done;
4363 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4364 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4366 memset(&lr, 0, sizeof(lr));
4367 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4368 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4369 data = lr.pBits;
4370 *data = 0x0f00f000;
4371 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4372 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4374 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4375 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4376 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4377 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4379 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4380 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4382 hr = IDirect3DDevice9_BeginScene(device);
4383 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4384 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4385 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4387 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4388 hr = IDirect3DDevice9_EndScene(device);
4389 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4391 color = getPixelColor(device, 240, 320);
4392 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4393 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4395 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4396 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4398 IDirect3DTexture9_Release(texture);
4399 refcount = IDirect3DDevice9_Release(device);
4400 ok(!refcount, "Device has %u references left.\n", refcount);
4401 done:
4402 IDirect3D9_Release(d3d);
4403 DestroyWindow(window);
4406 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4408 LONG x_coords[2][2] =
4410 {r.left - 1, r.left + 1},
4411 {r.right + 1, r.right - 1},
4413 LONG y_coords[2][2] =
4415 {r.top - 1, r.top + 1},
4416 {r.bottom + 1, r.bottom - 1}
4418 unsigned int i, j, x_side, y_side;
4420 for (i = 0; i < 2; ++i)
4422 for (j = 0; j < 2; ++j)
4424 for (x_side = 0; x_side < 2; ++x_side)
4426 for (y_side = 0; y_side < 2; ++y_side)
4428 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4429 DWORD color;
4430 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4432 color = getPixelColor(device, x, y);
4433 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4434 message, x, y, color, expected);
4441 struct projected_textures_test_run
4443 const char *message;
4444 DWORD flags;
4445 IDirect3DVertexDeclaration9 *decl;
4446 BOOL vs, ps;
4447 RECT rect;
4450 static void projected_textures_test(IDirect3DDevice9 *device,
4451 struct projected_textures_test_run tests[4])
4453 unsigned int i;
4455 static const DWORD vertex_shader[] =
4457 0xfffe0101, /* vs_1_1 */
4458 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4459 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4460 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4461 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4462 0x0000ffff /* end */
4464 static const DWORD pixel_shader[] =
4466 0xffff0103, /* ps_1_3 */
4467 0x00000042, 0xb00f0000, /* tex t0 */
4468 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4469 0x0000ffff /* end */
4471 IDirect3DVertexShader9 *vs = NULL;
4472 IDirect3DPixelShader9 *ps = NULL;
4473 IDirect3D9 *d3d;
4474 D3DCAPS9 caps;
4475 HRESULT hr;
4477 IDirect3DDevice9_GetDirect3D(device, &d3d);
4478 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4479 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4480 IDirect3D9_Release(d3d);
4482 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4484 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4485 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4487 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4489 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4490 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4496 hr = IDirect3DDevice9_BeginScene(device);
4497 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4499 for (i = 0; i < 4; ++i)
4501 DWORD value = 0xdeadbeef;
4502 static const float proj_quads[] =
4504 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4505 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4506 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4507 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4509 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4510 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4511 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4512 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4514 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4515 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4516 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4517 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4519 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4520 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4521 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4522 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4525 if (tests[i].vs)
4527 if (!vs)
4529 skip("Vertex shaders not supported, skipping\n");
4530 continue;
4532 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4534 else
4535 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4536 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4537 if (tests[i].ps)
4539 if (!ps)
4541 skip("Pixel shaders not supported, skipping\n");
4542 continue;
4544 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4546 else
4547 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4548 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4550 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4551 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4554 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4555 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4556 ok(SUCCEEDED(hr) && value == tests[i].flags,
4557 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4559 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4560 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4561 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4564 hr = IDirect3DDevice9_EndScene(device);
4565 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4567 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4568 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4569 if (vs) IDirect3DVertexShader9_Release(vs);
4570 if (ps) IDirect3DPixelShader9_Release(ps);
4572 for (i = 0; i < 4; ++i)
4574 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4575 check_rect(device, tests[i].rect, tests[i].message);
4578 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4579 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4582 static void texture_transform_flags_test(void)
4584 HRESULT hr;
4585 IDirect3D9 *d3d;
4586 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4587 D3DCAPS9 caps;
4588 IDirect3DTexture9 *texture = NULL;
4589 IDirect3DVolumeTexture9 *volume = NULL;
4590 IDirect3DDevice9 *device;
4591 unsigned int x, y, z;
4592 D3DLOCKED_RECT lr;
4593 D3DLOCKED_BOX lb;
4594 D3DCOLOR color;
4595 ULONG refcount;
4596 HWND window;
4597 UINT w, h;
4598 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4600 static const D3DVERTEXELEMENT9 decl_elements[] = {
4601 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4602 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4603 D3DDECL_END()
4605 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4606 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4607 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4608 D3DDECL_END()
4610 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4611 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4612 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4613 D3DDECL_END()
4615 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4616 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4617 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4618 D3DDECL_END()
4620 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4621 0x00, 0xff, 0x00, 0x00,
4622 0x00, 0x00, 0x00, 0x00,
4623 0x00, 0x00, 0x00, 0x00};
4624 static const D3DMATRIX identity =
4626 1.0f, 0.0f, 0.0f, 0.0f,
4627 0.0f, 1.0f, 0.0f, 0.0f,
4628 0.0f, 0.0f, 1.0f, 0.0f,
4629 0.0f, 0.0f, 0.0f, 1.0f,
4630 }}};
4632 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4633 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4634 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4635 ok(!!d3d, "Failed to create a D3D object.\n");
4636 if (!(device = create_device(d3d, window, window, TRUE)))
4638 skip("Failed to create a D3D device, skipping tests.\n");
4639 goto done;
4642 memset(&lr, 0, sizeof(lr));
4643 memset(&lb, 0, sizeof(lb));
4644 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4645 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4646 fmt = D3DFMT_A16B16G16R16;
4648 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4649 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4650 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4651 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4652 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4653 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4654 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4655 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4656 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4657 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4658 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4659 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4660 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4661 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4662 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4663 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4664 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4665 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4666 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4668 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4669 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4671 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4672 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4673 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4675 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4676 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4679 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4680 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4681 w = min(1024, caps.MaxTextureWidth);
4682 h = min(1024, caps.MaxTextureHeight);
4683 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4684 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4685 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4686 if (!texture)
4688 skip("Failed to create the test texture.\n");
4689 IDirect3DDevice9_Release(device);
4690 goto done;
4693 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4694 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4695 * 1.0 in red and green for the x and y coords
4697 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4698 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4699 for(y = 0; y < h; y++) {
4700 for(x = 0; x < w; x++) {
4701 double r_f = (double) y / (double) h;
4702 double g_f = (double) x / (double) w;
4703 if(fmt == D3DFMT_A16B16G16R16) {
4704 unsigned short r, g;
4705 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4706 r = (unsigned short) (r_f * 65536.0);
4707 g = (unsigned short) (g_f * 65536.0);
4708 dst[0] = r;
4709 dst[1] = g;
4710 dst[2] = 0;
4711 dst[3] = 65535;
4712 } else {
4713 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4714 unsigned char r = (unsigned char) (r_f * 255.0);
4715 unsigned char g = (unsigned char) (g_f * 255.0);
4716 dst[0] = 0;
4717 dst[1] = g;
4718 dst[2] = r;
4719 dst[3] = 255;
4723 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4724 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4725 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4726 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4728 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4729 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4730 hr = IDirect3DDevice9_BeginScene(device);
4731 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4732 if(SUCCEEDED(hr))
4734 static const float quad1[] =
4736 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4737 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4738 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4739 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4741 static const float quad2[] =
4743 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4744 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4745 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4746 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4748 static const float quad3[] =
4750 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4751 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4752 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4753 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4755 static const float quad4[] =
4757 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4758 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4759 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4760 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4762 D3DMATRIX mat =
4764 0.0f, 0.0f, 0.0f, 0.0f,
4765 0.0f, 0.0f, 0.0f, 0.0f,
4766 0.0f, 0.0f, 0.0f, 0.0f,
4767 0.0f, 0.0f, 0.0f, 0.0f,
4768 }}};
4770 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4771 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4774 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4776 /* What happens with transforms enabled? */
4777 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4778 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4782 /* What happens if 4 coords are used, but only 2 given ?*/
4783 U(mat).m[2][0] = 1.0f;
4784 U(mat).m[3][1] = 1.0f;
4785 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4786 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4787 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4788 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4790 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4792 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4793 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4794 * due to the coords in the vertices. (turns out red, indeed)
4796 memset(&mat, 0, sizeof(mat));
4797 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4798 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4799 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4800 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4802 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4804 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4806 hr = IDirect3DDevice9_EndScene(device);
4807 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4809 color = getPixelColor(device, 160, 360);
4810 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4811 color = getPixelColor(device, 160, 120);
4812 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4813 color = getPixelColor(device, 480, 120);
4814 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4815 color = getPixelColor(device, 480, 360);
4816 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4817 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4818 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4820 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4821 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4823 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4825 hr = IDirect3DDevice9_BeginScene(device);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4827 if(SUCCEEDED(hr))
4829 static const float quad1[] =
4831 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4832 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4833 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4834 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4836 static const float quad2[] =
4838 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4839 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4840 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4841 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4843 static const float quad3[] =
4845 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4846 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4847 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4848 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4850 static const float quad4[] =
4852 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4853 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4854 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4855 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4857 D3DMATRIX mat =
4859 0.0f, 0.0f, 0.0f, 0.0f,
4860 0.0f, 0.0f, 0.0f, 0.0f,
4861 0.0f, 1.0f, 0.0f, 0.0f,
4862 0.0f, 0.0f, 0.0f, 0.0f,
4863 }}};
4865 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4866 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4867 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4868 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4869 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4872 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4874 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4875 * it behaves like COUNT2 because normal textures require 2 coords. */
4876 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4877 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4881 /* Just to be sure, the same as quad2 above */
4882 memset(&mat, 0, sizeof(mat));
4883 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4884 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4885 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4886 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4887 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4888 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4890 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4891 * used? And what happens to the first? */
4892 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4893 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4895 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4897 hr = IDirect3DDevice9_EndScene(device);
4898 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4900 color = getPixelColor(device, 160, 360);
4901 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4902 color = getPixelColor(device, 160, 120);
4903 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4904 color = getPixelColor(device, 480, 120);
4905 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4906 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4907 color = getPixelColor(device, 480, 360);
4908 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4909 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4910 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4911 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4913 IDirect3DTexture9_Release(texture);
4915 /* Test projected textures, without any fancy matrices */
4916 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4917 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4918 if (SUCCEEDED(hr))
4920 struct projected_textures_test_run projected_tests_1[4] =
4923 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4924 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4925 decl3,
4926 FALSE, TRUE,
4927 {120, 300, 240, 390},
4930 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4931 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4932 decl3,
4933 FALSE, TRUE,
4934 {400, 360, 480, 420},
4936 /* Try with some invalid values */
4938 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4939 0xffffffff,
4940 decl3,
4941 FALSE, TRUE,
4942 {120, 60, 240, 150}
4945 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4946 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4947 decl4,
4948 FALSE, TRUE,
4949 {340, 210, 360, 225},
4952 struct projected_textures_test_run projected_tests_2[4] =
4955 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4956 D3DTTFF_PROJECTED,
4957 decl3,
4958 FALSE, TRUE,
4959 {120, 300, 240, 390},
4962 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4963 D3DTTFF_PROJECTED,
4964 decl,
4965 FALSE, TRUE,
4966 {400, 360, 480, 420},
4969 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4970 0xffffffff,
4971 decl,
4972 FALSE, TRUE,
4973 {80, 120, 160, 180},
4976 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4977 D3DTTFF_COUNT1,
4978 decl4,
4979 FALSE, TRUE,
4980 {340, 210, 360, 225},
4983 struct projected_textures_test_run projected_tests_3[4] =
4986 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4987 D3DTTFF_PROJECTED,
4988 decl3,
4989 TRUE, FALSE,
4990 {120, 300, 240, 390},
4993 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4994 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4995 decl3,
4996 TRUE, TRUE,
4997 {440, 300, 560, 390},
5000 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5001 0xffffffff,
5002 decl3,
5003 TRUE, TRUE,
5004 {120, 60, 240, 150},
5007 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5008 D3DTTFF_PROJECTED,
5009 decl3,
5010 FALSE, FALSE,
5011 {440, 60, 560, 150},
5015 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5016 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5018 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5019 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5020 for(x = 0; x < 4; x++) {
5021 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5023 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5024 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5025 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5026 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5028 projected_textures_test(device, projected_tests_1);
5029 projected_textures_test(device, projected_tests_2);
5030 projected_textures_test(device, projected_tests_3);
5032 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5033 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5034 IDirect3DTexture9_Release(texture);
5037 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5038 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5039 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5040 * Thus watch out if sampling from texels between 0 and 1.
5042 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5043 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5044 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5045 if(!volume) {
5046 skip("Failed to create a volume texture\n");
5047 goto out;
5050 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5051 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5052 for(z = 0; z < 32; z++) {
5053 for(y = 0; y < 32; y++) {
5054 for(x = 0; x < 32; x++) {
5055 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5056 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5057 float r_f = (float) x / 31.0;
5058 float g_f = (float) y / 31.0;
5059 float b_f = (float) z / 31.0;
5061 if(fmt == D3DFMT_A16B16G16R16) {
5062 unsigned short *mem_s = mem;
5063 mem_s[0] = r_f * 65535.0;
5064 mem_s[1] = g_f * 65535.0;
5065 mem_s[2] = b_f * 65535.0;
5066 mem_s[3] = 65535;
5067 } else {
5068 unsigned char *mem_c = mem;
5069 mem_c[0] = b_f * 255.0;
5070 mem_c[1] = g_f * 255.0;
5071 mem_c[2] = r_f * 255.0;
5072 mem_c[3] = 255;
5077 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5078 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5080 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5081 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5083 hr = IDirect3DDevice9_BeginScene(device);
5084 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5085 if(SUCCEEDED(hr))
5087 static const float quad1[] =
5089 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5090 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5091 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5092 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5094 static const float quad2[] =
5096 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5097 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5098 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5099 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5101 static const float quad3[] =
5103 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5104 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5105 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5106 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5108 static const float quad4[] =
5110 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5111 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5112 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5113 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5115 D3DMATRIX mat =
5117 1.0f, 0.0f, 0.0f, 0.0f,
5118 0.0f, 0.0f, 1.0f, 0.0f,
5119 0.0f, 1.0f, 0.0f, 0.0f,
5120 0.0f, 0.0f, 0.0f, 1.0f,
5121 }}};
5122 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5123 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5125 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5126 * values
5128 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5129 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5130 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5131 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5133 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5135 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5136 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5137 * otherwise the w will be missing(blue).
5138 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5139 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5141 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5143 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5145 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5146 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5147 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5148 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5149 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5151 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5153 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5155 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5156 * disable. ATI extends it up to the amount of values needed for the volume texture
5158 memset(&mat, 0, sizeof(mat));
5159 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5160 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5161 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5162 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5163 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5164 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5166 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5168 hr = IDirect3DDevice9_EndScene(device);
5169 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5172 color = getPixelColor(device, 160, 360);
5173 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5174 color = getPixelColor(device, 160, 120);
5175 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5176 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5177 color = getPixelColor(device, 480, 120);
5178 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5179 color = getPixelColor(device, 480, 360);
5180 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5182 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5183 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5185 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5186 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5187 hr = IDirect3DDevice9_BeginScene(device);
5188 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5189 if(SUCCEEDED(hr))
5191 static const float quad1[] =
5193 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5194 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5195 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5196 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5198 static const float quad2[] =
5200 -1.0f, 0.0f, 0.1f,
5201 -1.0f, 1.0f, 0.1f,
5202 0.0f, 0.0f, 0.1f,
5203 0.0f, 1.0f, 0.1f,
5205 static const float quad3[] =
5207 0.0f, 0.0f, 0.1f, 1.0f,
5208 0.0f, 1.0f, 0.1f, 1.0f,
5209 1.0f, 0.0f, 0.1f, 1.0f,
5210 1.0f, 1.0f, 0.1f, 1.0f,
5212 static const D3DMATRIX mat =
5214 0.0f, 0.0f, 0.0f, 0.0f,
5215 0.0f, 0.0f, 0.0f, 0.0f,
5216 0.0f, 0.0f, 0.0f, 0.0f,
5217 0.0f, 1.0f, 0.0f, 0.0f,
5218 }}};
5219 static const D3DMATRIX mat2 =
5221 0.0f, 0.0f, 0.0f, 1.0f,
5222 1.0f, 0.0f, 0.0f, 0.0f,
5223 0.0f, 1.0f, 0.0f, 0.0f,
5224 0.0f, 0.0f, 1.0f, 0.0f,
5225 }}};
5226 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5227 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5229 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5230 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5231 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5232 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5233 * 4th *input* coordinate.
5235 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5236 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5237 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5238 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5240 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5242 /* None passed */
5243 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5244 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5245 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5246 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5248 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5250 /* 4 used, 1 passed */
5251 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5253 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5254 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5255 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5256 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5258 hr = IDirect3DDevice9_EndScene(device);
5259 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5261 color = getPixelColor(device, 160, 360);
5262 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5263 color = getPixelColor(device, 160, 120);
5264 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5265 color = getPixelColor(device, 480, 120);
5266 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5267 /* Quad4: unused */
5269 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5270 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5272 IDirect3DVolumeTexture9_Release(volume);
5274 out:
5275 IDirect3DVertexDeclaration9_Release(decl);
5276 IDirect3DVertexDeclaration9_Release(decl2);
5277 IDirect3DVertexDeclaration9_Release(decl3);
5278 IDirect3DVertexDeclaration9_Release(decl4);
5279 refcount = IDirect3DDevice9_Release(device);
5280 ok(!refcount, "Device has %u references left.\n", refcount);
5281 done:
5282 IDirect3D9_Release(d3d);
5283 DestroyWindow(window);
5286 static void texdepth_test(void)
5288 IDirect3DPixelShader9 *shader;
5289 IDirect3DDevice9 *device;
5290 IDirect3D9 *d3d;
5291 ULONG refcount;
5292 D3DCAPS9 caps;
5293 DWORD color;
5294 HWND window;
5295 HRESULT hr;
5297 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5298 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5299 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5300 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5301 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5302 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5303 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5304 static const DWORD shader_code[] =
5306 0xffff0104, /* ps_1_4 */
5307 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5308 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5309 0x0000fffd, /* phase */
5310 0x00000057, 0x800f0005, /* texdepth r5 */
5311 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5312 0x0000ffff /* end */
5314 static const float vertex[] =
5316 -1.0f, -1.0f, 0.0f,
5317 -1.0f, 1.0f, 0.0f,
5318 1.0f, -1.0f, 1.0f,
5319 1.0f, 1.0f, 1.0f,
5322 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5323 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5324 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5325 ok(!!d3d, "Failed to create a D3D object.\n");
5326 if (!(device = create_device(d3d, window, window, TRUE)))
5328 skip("Failed to create a D3D device, skipping tests.\n");
5329 goto done;
5332 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5333 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5334 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5336 skip("No ps_1_1 support, skipping tests.\n");
5337 IDirect3DDevice9_Release(device);
5338 goto done;
5341 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5342 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5344 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5345 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5347 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5349 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5353 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5354 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5355 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5357 /* Fill the depth buffer with a gradient */
5358 hr = IDirect3DDevice9_BeginScene(device);
5359 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5361 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5362 hr = IDirect3DDevice9_EndScene(device);
5363 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5365 /* Now perform the actual tests. Same geometry, but with the shader */
5366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5369 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5370 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5371 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5373 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5374 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5375 hr = IDirect3DDevice9_BeginScene(device);
5376 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5378 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5379 hr = IDirect3DDevice9_EndScene(device);
5380 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5382 color = getPixelColor(device, 158, 240);
5383 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5384 color = getPixelColor(device, 162, 240);
5385 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5387 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5388 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5391 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5393 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5394 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5395 hr = IDirect3DDevice9_BeginScene(device);
5396 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5398 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5399 hr = IDirect3DDevice9_EndScene(device);
5400 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5402 color = getPixelColor(device, 318, 240);
5403 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5404 color = getPixelColor(device, 322, 240);
5405 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5408 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5411 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5413 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5414 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5415 hr = IDirect3DDevice9_BeginScene(device);
5416 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5418 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5419 hr = IDirect3DDevice9_EndScene(device);
5420 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5422 color = getPixelColor(device, 1, 240);
5423 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5426 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5428 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5429 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5431 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5432 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5433 hr = IDirect3DDevice9_BeginScene(device);
5434 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5436 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5437 hr = IDirect3DDevice9_EndScene(device);
5438 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5440 color = getPixelColor(device, 318, 240);
5441 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5442 color = getPixelColor(device, 322, 240);
5443 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5448 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5449 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5451 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5452 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5453 hr = IDirect3DDevice9_BeginScene(device);
5454 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5456 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5457 hr = IDirect3DDevice9_EndScene(device);
5458 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5460 color = getPixelColor(device, 1, 240);
5461 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5463 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5464 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5467 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5469 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5470 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5471 hr = IDirect3DDevice9_BeginScene(device);
5472 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5474 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5475 hr = IDirect3DDevice9_EndScene(device);
5476 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5478 color = getPixelColor(device, 638, 240);
5479 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5481 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5485 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5487 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5488 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5489 hr = IDirect3DDevice9_BeginScene(device);
5490 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5492 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5493 hr = IDirect3DDevice9_EndScene(device);
5494 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5496 color = getPixelColor(device, 638, 240);
5497 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5499 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5500 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5502 IDirect3DPixelShader9_Release(shader);
5503 refcount = IDirect3DDevice9_Release(device);
5504 ok(!refcount, "Device has %u references left.\n", refcount);
5505 done:
5506 IDirect3D9_Release(d3d);
5507 DestroyWindow(window);
5510 static void texkill_test(void)
5512 IDirect3DPixelShader9 *shader;
5513 IDirect3DDevice9 *device;
5514 IDirect3D9 *d3d;
5515 ULONG refcount;
5516 D3DCAPS9 caps;
5517 DWORD color;
5518 HWND window;
5519 HRESULT hr;
5521 static const float vertex[] =
5523 /* bottom top right left */
5524 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5525 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5526 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5527 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5529 static const DWORD shader_code_11[] =
5531 0xffff0101, /* ps_1_1 */
5532 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5533 0x00000041, 0xb00f0000, /* texkill t0 */
5534 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5535 0x0000ffff /* end */
5537 static const DWORD shader_code_20[] =
5539 0xffff0200, /* ps_2_0 */
5540 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5541 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5542 0x01000041, 0xb00f0000, /* texkill t0 */
5543 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5544 0x0000ffff /* end */
5547 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5548 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5549 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5550 ok(!!d3d, "Failed to create a D3D object.\n");
5551 if (!(device = create_device(d3d, window, window, TRUE)))
5553 skip("Failed to create a D3D device, skipping tests.\n");
5554 goto done;
5557 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5558 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5559 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5561 skip("No ps_1_1 support, skipping tests.\n");
5562 IDirect3DDevice9_Release(device);
5563 goto done;
5566 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5567 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5568 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5569 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5571 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5573 hr = IDirect3DDevice9_BeginScene(device);
5574 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5576 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5578 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5579 hr = IDirect3DDevice9_EndScene(device);
5580 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5582 color = getPixelColor(device, 63, 46);
5583 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5584 color = getPixelColor(device, 66, 46);
5585 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5586 color = getPixelColor(device, 63, 49);
5587 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5588 color = getPixelColor(device, 66, 49);
5589 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5591 color = getPixelColor(device, 578, 46);
5592 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5593 color = getPixelColor(device, 575, 46);
5594 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5595 color = getPixelColor(device, 578, 49);
5596 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5597 color = getPixelColor(device, 575, 49);
5598 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5600 color = getPixelColor(device, 63, 430);
5601 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5602 color = getPixelColor(device, 63, 433);
5603 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5604 color = getPixelColor(device, 66, 433);
5605 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5606 color = getPixelColor(device, 66, 430);
5607 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5609 color = getPixelColor(device, 578, 430);
5610 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5611 color = getPixelColor(device, 578, 433);
5612 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5613 color = getPixelColor(device, 575, 433);
5614 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5615 color = getPixelColor(device, 575, 430);
5616 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5621 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5622 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5623 IDirect3DPixelShader9_Release(shader);
5625 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5626 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5627 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5629 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5630 IDirect3DDevice9_Release(device);
5631 goto done;
5634 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5635 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5636 hr = IDirect3DDevice9_BeginScene(device);
5637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5639 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5640 hr = IDirect3DDevice9_EndScene(device);
5641 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5643 color = getPixelColor(device, 63, 46);
5644 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5645 color = getPixelColor(device, 66, 46);
5646 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5647 color = getPixelColor(device, 63, 49);
5648 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5649 color = getPixelColor(device, 66, 49);
5650 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5652 color = getPixelColor(device, 578, 46);
5653 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5654 color = getPixelColor(device, 575, 46);
5655 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5656 color = getPixelColor(device, 578, 49);
5657 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5658 color = getPixelColor(device, 575, 49);
5659 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5661 color = getPixelColor(device, 63, 430);
5662 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5663 color = getPixelColor(device, 63, 433);
5664 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5665 color = getPixelColor(device, 66, 433);
5666 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5667 color = getPixelColor(device, 66, 430);
5668 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5670 color = getPixelColor(device, 578, 430);
5671 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5672 color = getPixelColor(device, 578, 433);
5673 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5674 color = getPixelColor(device, 575, 433);
5675 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5676 color = getPixelColor(device, 575, 430);
5677 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5679 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5680 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5682 IDirect3DPixelShader9_Release(shader);
5683 refcount = IDirect3DDevice9_Release(device);
5684 ok(!refcount, "Device has %u references left.\n", refcount);
5685 done:
5686 IDirect3D9_Release(d3d);
5687 DestroyWindow(window);
5690 static void autogen_mipmap_test(void)
5692 IDirect3DTexture9 *texture = NULL;
5693 IDirect3DSurface9 *surface;
5694 IDirect3DDevice9 *device;
5695 unsigned int x, y;
5696 D3DLOCKED_RECT lr;
5697 IDirect3D9 *d3d;
5698 D3DCOLOR color;
5699 ULONG refcount;
5700 HWND window;
5701 HRESULT hr;
5703 static const RECT r1 = {256, 256, 512, 512};
5704 static const RECT r2 = {512, 256, 768, 512};
5705 static const RECT r3 = {256, 512, 512, 768};
5706 static const RECT r4 = {512, 512, 768, 768};
5707 static const float quad[] =
5709 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5710 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5711 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5712 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5715 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5716 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5717 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5718 ok(!!d3d, "Failed to create a D3D object.\n");
5719 if (!(device = create_device(d3d, window, window, TRUE)))
5721 skip("Failed to create a D3D device, skipping tests.\n");
5722 goto done;
5725 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5726 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5728 skip("No autogenmipmap support.\n");
5729 IDirect3DDevice9_Release(device);
5730 goto done;
5733 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5734 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5736 /* Make the mipmap big, so that a smaller mipmap is used
5738 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5739 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5740 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5742 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5743 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5744 memset(&lr, 0, sizeof(lr));
5745 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5746 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5747 for(y = 0; y < 1024; y++) {
5748 for(x = 0; x < 1024; x++) {
5749 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5750 POINT pt;
5752 pt.x = x;
5753 pt.y = y;
5754 if(PtInRect(&r1, pt)) {
5755 *dst = 0xffff0000;
5756 } else if(PtInRect(&r2, pt)) {
5757 *dst = 0xff00ff00;
5758 } else if(PtInRect(&r3, pt)) {
5759 *dst = 0xff0000ff;
5760 } else if(PtInRect(&r4, pt)) {
5761 *dst = 0xff000000;
5762 } else {
5763 *dst = 0xffffffff;
5767 hr = IDirect3DSurface9_UnlockRect(surface);
5768 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5769 IDirect3DSurface9_Release(surface);
5771 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5773 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5774 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5775 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5776 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5778 hr = IDirect3DDevice9_BeginScene(device);
5779 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5780 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5781 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5783 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5784 hr = IDirect3DDevice9_EndScene(device);
5785 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5786 IDirect3DTexture9_Release(texture);
5788 color = getPixelColor(device, 200, 200);
5789 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5790 color = getPixelColor(device, 280, 200);
5791 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5792 color = getPixelColor(device, 360, 200);
5793 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5794 color = getPixelColor(device, 440, 200);
5795 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5796 color = getPixelColor(device, 200, 270);
5797 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5798 color = getPixelColor(device, 280, 270);
5799 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5800 color = getPixelColor(device, 360, 270);
5801 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5802 color = getPixelColor(device, 440, 270);
5803 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5805 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5807 refcount = IDirect3DDevice9_Release(device);
5808 ok(!refcount, "Device has %u references left.\n", refcount);
5809 done:
5810 IDirect3D9_Release(d3d);
5811 DestroyWindow(window);
5814 static void test_constant_clamp_vs(void)
5816 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5817 IDirect3DVertexDeclaration9 *decl;
5818 IDirect3DDevice9 *device;
5819 IDirect3D9 *d3d;
5820 D3DCOLOR color;
5821 ULONG refcount;
5822 D3DCAPS9 caps;
5823 HWND window;
5824 HRESULT hr;
5826 static const DWORD shader_code_11[] =
5828 0xfffe0101, /* vs_1_1 */
5829 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5830 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5831 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5832 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5833 0x0000ffff /* end */
5835 static const DWORD shader_code_11_2[] =
5837 0xfffe0101, /* vs_1_1 */
5838 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5839 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5840 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5841 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5842 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5843 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5844 0x0000ffff /* end */
5846 static const DWORD shader_code_20[] =
5848 0xfffe0200, /* vs_2_0 */
5849 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5850 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5851 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5852 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5853 0x0000ffff /* end */
5855 static const DWORD shader_code_20_2[] =
5857 0xfffe0200, /* vs_2_0 */
5858 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5859 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5860 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5861 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5862 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5863 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5864 0x0000ffff /* end */
5866 static const D3DVERTEXELEMENT9 decl_elements[] =
5868 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5869 D3DDECL_END()
5871 static const float quad1[] =
5873 -1.0f, -1.0f, 0.1f,
5874 -1.0f, 0.0f, 0.1f,
5875 0.0f, -1.0f, 0.1f,
5876 0.0f, 0.0f, 0.1f,
5878 static const float quad2[] =
5880 0.0f, -1.0f, 0.1f,
5881 0.0f, 0.0f, 0.1f,
5882 1.0f, -1.0f, 0.1f,
5883 1.0f, 0.0f, 0.1f,
5885 static const float quad3[] =
5887 0.0f, 0.0f, 0.1f,
5888 0.0f, 1.0f, 0.1f,
5889 1.0f, 0.0f, 0.1f,
5890 1.0f, 1.0f, 0.1f,
5892 static const float quad4[] =
5894 -1.0f, 0.0f, 0.1f,
5895 -1.0f, 1.0f, 0.1f,
5896 0.0f, 0.0f, 0.1f,
5897 0.0f, 1.0f, 0.1f,
5899 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5900 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5902 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5903 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5904 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5905 ok(!!d3d, "Failed to create a D3D object.\n");
5906 if (!(device = create_device(d3d, window, window, TRUE)))
5908 skip("Failed to create a D3D device, skipping tests.\n");
5909 goto done;
5912 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5913 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5914 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
5916 skip("No vs_1_1 support, skipping tests.\n");
5917 IDirect3DDevice9_Release(device);
5918 goto done;
5921 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5922 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5924 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5925 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5926 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5927 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5928 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5929 if(FAILED(hr)) shader_20 = NULL;
5930 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5931 if(FAILED(hr)) shader_20_2 = NULL;
5932 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5933 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5935 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5936 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5937 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5938 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5939 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5940 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5942 hr = IDirect3DDevice9_BeginScene(device);
5943 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5945 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5946 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5948 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5950 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5951 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5953 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5955 if (shader_20)
5957 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5958 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5960 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5963 if (shader_20_2)
5965 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5966 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5968 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5971 hr = IDirect3DDevice9_EndScene(device);
5972 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5974 color = getPixelColor(device, 160, 360);
5975 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5976 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5977 color = getPixelColor(device, 480, 360);
5978 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5979 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5980 if(shader_20) {
5981 color = getPixelColor(device, 480, 120);
5982 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5983 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5985 if(shader_20_2) {
5986 color = getPixelColor(device, 160, 120);
5987 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5988 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5991 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5993 IDirect3DVertexDeclaration9_Release(decl);
5994 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5995 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5996 IDirect3DVertexShader9_Release(shader_11_2);
5997 IDirect3DVertexShader9_Release(shader_11);
5998 refcount = IDirect3DDevice9_Release(device);
5999 ok(!refcount, "Device has %u references left.\n", refcount);
6000 done:
6001 IDirect3D9_Release(d3d);
6002 DestroyWindow(window);
6005 static void constant_clamp_ps_test(void)
6007 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6008 IDirect3DDevice9 *device;
6009 IDirect3D9 *d3d;
6010 ULONG refcount;
6011 D3DCAPS9 caps;
6012 DWORD color;
6013 HWND window;
6014 HRESULT hr;
6016 static const DWORD shader_code_11[] =
6018 0xffff0101, /* ps_1_1 */
6019 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6020 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6021 0x0000ffff /* end */
6023 static const DWORD shader_code_12[] =
6025 0xffff0102, /* ps_1_2 */
6026 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6027 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6028 0x0000ffff /* end */
6030 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6031 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6032 * unlikely that 1.3 shaders are different. During development of this
6033 * test, 1.3 shaders were verified too. */
6034 static const DWORD shader_code_14[] =
6036 0xffff0104, /* ps_1_4 */
6037 /* Try to make one constant local. It gets clamped too, although the
6038 * binary contains the bigger numbers. */
6039 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6040 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6041 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6042 0x0000ffff /* end */
6044 static const DWORD shader_code_20[] =
6046 0xffff0200, /* ps_2_0 */
6047 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6048 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6049 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6050 0x0000ffff /* end */
6052 static const float quad1[] =
6054 -1.0f, -1.0f, 0.1f,
6055 -1.0f, 0.0f, 0.1f,
6056 0.0f, -1.0f, 0.1f,
6057 0.0f, 0.0f, 0.1f,
6059 static const float quad2[] =
6061 0.0f, -1.0f, 0.1f,
6062 0.0f, 0.0f, 0.1f,
6063 1.0f, -1.0f, 0.1f,
6064 1.0f, 0.0f, 0.1f,
6066 static const float quad3[] =
6068 0.0f, 0.0f, 0.1f,
6069 0.0f, 1.0f, 0.1f,
6070 1.0f, 0.0f, 0.1f,
6071 1.0f, 1.0f, 0.1f,
6073 static const float quad4[] =
6075 -1.0f, 0.0f, 0.1f,
6076 -1.0f, 1.0f, 0.1f,
6077 0.0f, 0.0f, 0.1f,
6078 0.0f, 1.0f, 0.1f,
6080 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6081 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6083 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6084 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6085 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6086 ok(!!d3d, "Failed to create a D3D object.\n");
6087 if (!(device = create_device(d3d, window, window, TRUE)))
6089 skip("Failed to create a D3D device, skipping tests.\n");
6090 goto done;
6093 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6094 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6095 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6097 skip("No ps_1_4 support, skipping tests.\n");
6098 IDirect3DDevice9_Release(device);
6099 goto done;
6102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6103 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6105 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6106 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6107 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6108 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6109 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6110 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6111 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6112 if(FAILED(hr)) shader_20 = NULL;
6114 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6115 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6116 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6117 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6118 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6119 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6121 hr = IDirect3DDevice9_BeginScene(device);
6122 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6124 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6125 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6126 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6127 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6129 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6130 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6132 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6134 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6135 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6137 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6139 if (shader_20)
6141 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6142 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6143 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6144 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6147 hr = IDirect3DDevice9_EndScene(device);
6148 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6150 color = getPixelColor(device, 160, 360);
6151 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6152 "quad 1 has color %08x, expected 0x00808000\n", color);
6153 color = getPixelColor(device, 480, 360);
6154 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6155 "quad 2 has color %08x, expected 0x00808000\n", color);
6156 color = getPixelColor(device, 480, 120);
6157 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6158 "quad 3 has color %08x, expected 0x00808000\n", color);
6159 if(shader_20) {
6160 color = getPixelColor(device, 160, 120);
6161 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6162 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6165 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6167 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6168 IDirect3DPixelShader9_Release(shader_14);
6169 IDirect3DPixelShader9_Release(shader_12);
6170 IDirect3DPixelShader9_Release(shader_11);
6171 refcount = IDirect3DDevice9_Release(device);
6172 ok(!refcount, "Device has %u references left.\n", refcount);
6173 done:
6174 IDirect3D9_Release(d3d);
6175 DestroyWindow(window);
6178 static void dp2add_ps_test(void)
6180 IDirect3DPixelShader9 *shader_dp2add_sat;
6181 IDirect3DPixelShader9 *shader_dp2add;
6182 IDirect3DDevice9 *device;
6183 IDirect3D9 *d3d;
6184 ULONG refcount;
6185 D3DCAPS9 caps;
6186 DWORD color;
6187 HWND window;
6188 HRESULT hr;
6190 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6191 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6192 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6193 * r0 first.
6194 * The result here for the r,g,b components should be roughly 0.5:
6195 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6196 static const DWORD shader_code_dp2add[] = {
6197 0xffff0200, /* ps_2_0 */
6198 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6200 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6201 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6203 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6204 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6205 0x0000ffff /* end */
6208 /* Test the _sat modifier, too. Result here should be:
6209 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6210 * _SAT: ==> 1.0
6211 * ADD: (1.0 + -0.5) = 0.5
6213 static const DWORD shader_code_dp2add_sat[] = {
6214 0xffff0200, /* ps_2_0 */
6215 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6217 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6218 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6219 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6221 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6222 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6223 0x0000ffff /* end */
6225 static const float quad[] =
6227 -1.0f, -1.0f, 0.1f,
6228 -1.0f, 1.0f, 0.1f,
6229 1.0f, -1.0f, 0.1f,
6230 1.0f, 1.0f, 0.1f,
6233 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6234 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6235 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6236 ok(!!d3d, "Failed to create a D3D object.\n");
6237 if (!(device = create_device(d3d, window, window, TRUE)))
6239 skip("Failed to create a D3D device, skipping tests.\n");
6240 goto done;
6243 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6244 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6245 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6247 skip("No ps_2_0 support, skipping tests.\n");
6248 IDirect3DDevice9_Release(device);
6249 goto done;
6252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6253 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6255 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6258 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6259 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6261 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6262 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6264 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6265 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6266 hr = IDirect3DDevice9_BeginScene(device);
6267 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6269 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6270 hr = IDirect3DDevice9_EndScene(device);
6271 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6273 color = getPixelColor(device, 360, 240);
6274 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6276 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6277 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6278 IDirect3DPixelShader9_Release(shader_dp2add);
6280 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6281 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6282 hr = IDirect3DDevice9_BeginScene(device);
6283 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6285 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6286 hr = IDirect3DDevice9_EndScene(device);
6287 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6289 color = getPixelColor(device, 360, 240);
6290 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6292 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6293 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6294 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6296 refcount = IDirect3DDevice9_Release(device);
6297 ok(!refcount, "Device has %u references left.\n", refcount);
6298 done:
6299 IDirect3D9_Release(d3d);
6300 DestroyWindow(window);
6303 static void cnd_test(void)
6305 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6306 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6307 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6308 IDirect3DDevice9 *device;
6309 IDirect3D9 *d3d;
6310 ULONG refcount;
6311 D3DCAPS9 caps;
6312 HWND window;
6313 DWORD color;
6314 HRESULT hr;
6316 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6317 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6318 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6319 * in 1.x pixel shaders. */
6320 static const DWORD shader_code_11[] =
6322 0xffff0101, /* ps_1_1 */
6323 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6324 0x00000040, 0xb00f0000, /* texcoord t0 */
6325 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6326 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6327 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6328 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6329 0x0000ffff /* end */
6331 static const DWORD shader_code_12[] =
6333 0xffff0102, /* ps_1_2 */
6334 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6335 0x00000040, 0xb00f0000, /* texcoord t0 */
6336 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6337 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6338 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6339 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6340 0x0000ffff /* end */
6342 static const DWORD shader_code_13[] =
6344 0xffff0103, /* ps_1_3 */
6345 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6346 0x00000040, 0xb00f0000, /* texcoord t0 */
6347 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6348 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6349 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6350 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6351 0x0000ffff /* end */
6353 static const DWORD shader_code_14[] =
6355 0xffff0104, /* ps_1_3 */
6356 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6357 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6358 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6359 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6360 0x0000ffff /* end */
6363 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6364 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6365 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6366 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6367 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6368 * well enough.
6370 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6371 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6372 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6373 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6375 static const DWORD shader_code_11_coissue[] =
6377 0xffff0101, /* ps_1_1 */
6378 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6379 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6380 0x00000040, 0xb00f0000, /* texcoord t0 */
6381 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6382 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6383 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6384 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6385 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6386 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6387 0x0000ffff /* end */
6389 static const DWORD shader_code_11_coissue_2[] =
6391 0xffff0101, /* ps_1_1 */
6392 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6393 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6394 0x00000040, 0xb00f0000, /* texcoord t0 */
6395 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6396 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6397 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6398 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6399 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6400 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6401 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6402 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6403 0x0000ffff /* end */
6405 static const DWORD shader_code_12_coissue[] =
6407 0xffff0102, /* ps_1_2 */
6408 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6409 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6410 0x00000040, 0xb00f0000, /* texcoord t0 */
6411 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6412 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6413 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6414 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6415 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6416 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6417 0x0000ffff /* end */
6419 static const DWORD shader_code_12_coissue_2[] =
6421 0xffff0102, /* ps_1_2 */
6422 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6423 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6424 0x00000040, 0xb00f0000, /* texcoord t0 */
6425 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6426 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6427 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6428 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6429 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6430 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6431 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6432 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6433 0x0000ffff /* end */
6435 static const DWORD shader_code_13_coissue[] =
6437 0xffff0103, /* ps_1_3 */
6438 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6439 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6440 0x00000040, 0xb00f0000, /* texcoord t0 */
6441 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6442 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6443 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6444 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6445 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6446 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6447 0x0000ffff /* end */
6449 static const DWORD shader_code_13_coissue_2[] =
6451 0xffff0103, /* ps_1_3 */
6452 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6453 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6454 0x00000040, 0xb00f0000, /* texcoord t0 */
6455 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6456 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6457 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6458 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6459 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6460 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6461 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6462 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6463 0x0000ffff /* end */
6465 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6466 * texcrd result to cnd, it will compare against 0.5. */
6467 static const DWORD shader_code_14_coissue[] =
6469 0xffff0104, /* ps_1_4 */
6470 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6471 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6472 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6473 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6474 0x0000ffff /* end */
6476 static const DWORD shader_code_14_coissue_2[] =
6478 0xffff0104, /* ps_1_4 */
6479 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6480 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6481 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6482 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6483 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6484 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6485 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6486 0x0000ffff /* end */
6488 static const float quad1[] =
6490 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6491 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6492 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6493 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6495 static const float quad2[] =
6497 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6498 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6499 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6500 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6502 static const float quad3[] =
6504 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6505 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6506 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6507 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6509 static const float quad4[] =
6511 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6512 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6513 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6514 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6516 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6517 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6518 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6519 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6521 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6522 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6523 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6524 ok(!!d3d, "Failed to create a D3D object.\n");
6525 if (!(device = create_device(d3d, window, window, TRUE)))
6527 skip("Failed to create a D3D device, skipping tests.\n");
6528 goto done;
6531 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6532 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6533 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6535 skip("No ps_1_4 support, skipping tests.\n");
6536 IDirect3DDevice9_Release(device);
6537 goto done;
6540 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6541 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6543 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6544 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6545 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6546 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6547 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6548 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6549 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6550 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6551 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6552 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6553 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6554 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6555 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6556 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6557 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6558 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6559 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6560 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6561 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6562 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6563 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6564 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6565 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6566 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6568 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6569 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6570 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6571 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6573 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6575 hr = IDirect3DDevice9_BeginScene(device);
6576 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6578 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6579 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6581 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6583 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6584 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6586 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6588 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6589 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6590 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6591 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6593 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6594 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6598 hr = IDirect3DDevice9_EndScene(device);
6599 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6601 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6602 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6604 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6605 color = getPixelColor(device, 158, 118);
6606 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6607 color = getPixelColor(device, 162, 118);
6608 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6609 color = getPixelColor(device, 158, 122);
6610 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6611 color = getPixelColor(device, 162, 122);
6612 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6614 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6615 color = getPixelColor(device, 158, 358);
6616 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6617 color = getPixelColor(device, 162, 358);
6618 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6619 color = getPixelColor(device, 158, 362);
6620 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6621 color = getPixelColor(device, 162, 362);
6622 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6624 /* 1.2 shader */
6625 color = getPixelColor(device, 478, 358);
6626 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6627 color = getPixelColor(device, 482, 358);
6628 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6629 color = getPixelColor(device, 478, 362);
6630 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6631 color = getPixelColor(device, 482, 362);
6632 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6634 /* 1.3 shader */
6635 color = getPixelColor(device, 478, 118);
6636 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6637 color = getPixelColor(device, 482, 118);
6638 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6639 color = getPixelColor(device, 478, 122);
6640 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6641 color = getPixelColor(device, 482, 122);
6642 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6644 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6645 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6648 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6649 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6650 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6651 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6652 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6654 hr = IDirect3DDevice9_BeginScene(device);
6655 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6657 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6658 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6660 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6662 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6663 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6665 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6667 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6668 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6670 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6672 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6673 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6675 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6677 hr = IDirect3DDevice9_EndScene(device);
6678 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6680 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6681 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6683 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6684 * that we swapped the values in c1 and c2 to make the other tests return some color
6686 color = getPixelColor(device, 158, 118);
6687 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6688 color = getPixelColor(device, 162, 118);
6689 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6690 color = getPixelColor(device, 158, 122);
6691 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6692 color = getPixelColor(device, 162, 122);
6693 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6695 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6696 * (The Win7 nvidia driver always selects c2)
6698 color = getPixelColor(device, 158, 358);
6699 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6700 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6701 color = getPixelColor(device, 162, 358);
6702 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6703 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6704 color = getPixelColor(device, 158, 362);
6705 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6706 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6707 color = getPixelColor(device, 162, 362);
6708 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6709 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6711 /* 1.2 shader */
6712 color = getPixelColor(device, 478, 358);
6713 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6714 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6715 color = getPixelColor(device, 482, 358);
6716 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6717 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6718 color = getPixelColor(device, 478, 362);
6719 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6720 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6721 color = getPixelColor(device, 482, 362);
6722 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6723 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6725 /* 1.3 shader */
6726 color = getPixelColor(device, 478, 118);
6727 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6728 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6729 color = getPixelColor(device, 482, 118);
6730 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6731 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6732 color = getPixelColor(device, 478, 122);
6733 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6734 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6735 color = getPixelColor(device, 482, 122);
6736 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6737 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6739 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6742 /* Retest with the coissue flag on the alpha instruction instead. This
6743 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6744 * the same as coissue on .rgb. */
6745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6748 hr = IDirect3DDevice9_BeginScene(device);
6749 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6751 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6752 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6754 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6756 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6757 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6759 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6761 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6762 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6764 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6766 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6767 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6769 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6771 hr = IDirect3DDevice9_EndScene(device);
6772 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6774 /* 1.4 shader */
6775 color = getPixelColor(device, 158, 118);
6776 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6777 color = getPixelColor(device, 162, 118);
6778 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6779 color = getPixelColor(device, 158, 122);
6780 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6781 color = getPixelColor(device, 162, 122);
6782 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6784 /* 1.1 shader */
6785 color = getPixelColor(device, 238, 358);
6786 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6787 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6788 color = getPixelColor(device, 242, 358);
6789 ok(color_match(color, 0x00000000, 1),
6790 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6791 color = getPixelColor(device, 238, 362);
6792 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6793 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6794 color = getPixelColor(device, 242, 362);
6795 ok(color_match(color, 0x00000000, 1),
6796 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6798 /* 1.2 shader */
6799 color = getPixelColor(device, 558, 358);
6800 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6801 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6802 color = getPixelColor(device, 562, 358);
6803 ok(color_match(color, 0x00000000, 1),
6804 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6805 color = getPixelColor(device, 558, 362);
6806 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6807 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6808 color = getPixelColor(device, 562, 362);
6809 ok(color_match(color, 0x00000000, 1),
6810 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6812 /* 1.3 shader */
6813 color = getPixelColor(device, 558, 118);
6814 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6815 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6816 color = getPixelColor(device, 562, 118);
6817 ok(color_match(color, 0x00000000, 1),
6818 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6819 color = getPixelColor(device, 558, 122);
6820 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6821 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6822 color = getPixelColor(device, 562, 122);
6823 ok(color_match(color, 0x00000000, 1),
6824 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6827 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6829 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6830 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6831 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6832 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6833 IDirect3DPixelShader9_Release(shader_14_coissue);
6834 IDirect3DPixelShader9_Release(shader_13_coissue);
6835 IDirect3DPixelShader9_Release(shader_12_coissue);
6836 IDirect3DPixelShader9_Release(shader_11_coissue);
6837 IDirect3DPixelShader9_Release(shader_14);
6838 IDirect3DPixelShader9_Release(shader_13);
6839 IDirect3DPixelShader9_Release(shader_12);
6840 IDirect3DPixelShader9_Release(shader_11);
6841 refcount = IDirect3DDevice9_Release(device);
6842 ok(!refcount, "Device has %u references left.\n", refcount);
6843 done:
6844 IDirect3D9_Release(d3d);
6845 DestroyWindow(window);
6848 static void nested_loop_test(void)
6850 IDirect3DVertexShader9 *vshader;
6851 IDirect3DPixelShader9 *shader;
6852 IDirect3DDevice9 *device;
6853 IDirect3D9 *d3d;
6854 ULONG refcount;
6855 D3DCAPS9 caps;
6856 DWORD color;
6857 HWND window;
6858 HRESULT hr;
6860 static const DWORD shader_code[] =
6862 0xffff0300, /* ps_3_0 */
6863 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6864 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6865 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
6866 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6867 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6868 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6869 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6870 0x0000001d, /* endloop */
6871 0x0000001d, /* endloop */
6872 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6873 0x0000ffff /* end */
6875 static const DWORD vshader_code[] =
6877 0xfffe0300, /* vs_3_0 */
6878 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6879 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6880 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6881 0x0000ffff /* end */
6883 static const float quad[] =
6885 -1.0f, -1.0f, 0.1f,
6886 -1.0f, 1.0f, 0.1f,
6887 1.0f, -1.0f, 0.1f,
6888 1.0f, 1.0f, 0.1f,
6891 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6892 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6893 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6894 ok(!!d3d, "Failed to create a D3D object.\n");
6895 if (!(device = create_device(d3d, window, window, TRUE)))
6897 skip("Failed to create a D3D device, skipping tests.\n");
6898 goto done;
6901 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6902 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6903 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6905 skip("No shader model 3 support, skipping tests.\n");
6906 IDirect3DDevice9_Release(device);
6907 goto done;
6910 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6911 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6912 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6914 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6915 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6916 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6917 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6918 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6919 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
6921 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6923 hr = IDirect3DDevice9_BeginScene(device);
6924 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6926 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6927 hr = IDirect3DDevice9_EndScene(device);
6928 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6930 color = getPixelColor(device, 360, 240);
6931 ok(color_match(color, 0x00800000, 1),
6932 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
6934 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6935 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6937 IDirect3DPixelShader9_Release(shader);
6938 IDirect3DVertexShader9_Release(vshader);
6939 refcount = IDirect3DDevice9_Release(device);
6940 ok(!refcount, "Device has %u references left.\n", refcount);
6941 done:
6942 IDirect3D9_Release(d3d);
6943 DestroyWindow(window);
6946 static void pretransformed_varying_test(void)
6948 /* dcl_position: fails to compile */
6949 static const DWORD blendweight_code[] =
6951 0xffff0300, /* ps_3_0 */
6952 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6953 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6954 0x0000ffff /* end */
6956 static const DWORD blendindices_code[] =
6958 0xffff0300, /* ps_3_0 */
6959 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6960 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6961 0x0000ffff /* end */
6963 static const DWORD normal_code[] =
6965 0xffff0300, /* ps_3_0 */
6966 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6967 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6968 0x0000ffff /* end */
6970 /* psize: fails? */
6971 static const DWORD texcoord0_code[] =
6973 0xffff0300, /* ps_3_0 */
6974 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6975 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6976 0x0000ffff /* end */
6978 static const DWORD tangent_code[] =
6980 0xffff0300, /* ps_3_0 */
6981 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6982 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6983 0x0000ffff /* end */
6985 static const DWORD binormal_code[] =
6987 0xffff0300, /* ps_3_0 */
6988 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6989 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6990 0x0000ffff /* end */
6992 /* tessfactor: fails */
6993 /* positiont: fails */
6994 static const DWORD color_code[] =
6996 0xffff0300, /* ps_3_0 */
6997 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6998 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6999 0x0000ffff /* end */
7001 static const DWORD fog_code[] =
7003 0xffff0300, /* ps_3_0 */
7004 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7005 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7006 0x0000ffff /* end */
7008 static const DWORD depth_code[] =
7010 0xffff0300, /* ps_3_0 */
7011 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7012 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7013 0x0000ffff /* end */
7015 static const DWORD specular_code[] =
7017 0xffff0300, /* ps_3_0 */
7018 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7019 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7020 0x0000ffff /* end */
7022 /* sample: fails */
7024 static const struct
7026 const char *name;
7027 const DWORD *shader_code;
7028 DWORD color;
7029 BOOL todo;
7031 tests[] =
7033 {"blendweight", blendweight_code, 0x00191919, TRUE },
7034 {"blendindices", blendindices_code, 0x00333333, TRUE },
7035 {"normal", normal_code, 0x004c4c4c, TRUE },
7036 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7037 {"tangent", tangent_code, 0x00999999, TRUE },
7038 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7039 {"color", color_code, 0x00e6e6e6, FALSE},
7040 {"fog", fog_code, 0x00666666, TRUE },
7041 {"depth", depth_code, 0x00cccccc, TRUE },
7042 {"specular", specular_code, 0x004488ff, FALSE},
7044 /* Declare a monster vertex type :-) */
7045 static const D3DVERTEXELEMENT9 decl_elements[] = {
7046 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7047 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7048 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7049 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7050 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7051 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7052 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7053 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7054 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7055 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7056 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7057 D3DDECL_END()
7060 static const struct
7062 float pos_x, pos_y, pos_z, rhw;
7063 float weight_1, weight_2, weight_3, weight_4;
7064 float index_1, index_2, index_3, index_4;
7065 float normal_1, normal_2, normal_3, normal_4;
7066 float fog_1, fog_2, fog_3, fog_4;
7067 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7068 float tangent_1, tangent_2, tangent_3, tangent_4;
7069 float binormal_1, binormal_2, binormal_3, binormal_4;
7070 float depth_1, depth_2, depth_3, depth_4;
7071 D3DCOLOR diffuse;
7072 D3DCOLOR specular;
7074 data[] =
7077 0.0f, 0.0f, 0.1f, 1.0f,
7078 0.1f, 0.1f, 0.1f, 0.1f,
7079 0.2f, 0.2f, 0.2f, 0.2f,
7080 0.3f, 0.3f, 0.3f, 0.3f,
7081 0.4f, 0.4f, 0.4f, 0.4f,
7082 0.5f, 0.55f, 0.55f, 0.55f,
7083 0.6f, 0.6f, 0.6f, 0.7f,
7084 0.7f, 0.7f, 0.7f, 0.6f,
7085 0.8f, 0.8f, 0.8f, 0.8f,
7086 0xe6e6e6e6, /* 0.9 * 256 */
7087 0x224488ff, /* Nothing special */
7090 640.0f, 0.0f, 0.1f, 1.0f,
7091 0.1f, 0.1f, 0.1f, 0.1f,
7092 0.2f, 0.2f, 0.2f, 0.2f,
7093 0.3f, 0.3f, 0.3f, 0.3f,
7094 0.4f, 0.4f, 0.4f, 0.4f,
7095 0.5f, 0.55f, 0.55f, 0.55f,
7096 0.6f, 0.6f, 0.6f, 0.7f,
7097 0.7f, 0.7f, 0.7f, 0.6f,
7098 0.8f, 0.8f, 0.8f, 0.8f,
7099 0xe6e6e6e6, /* 0.9 * 256 */
7100 0x224488ff, /* Nothing special */
7103 0.0f, 480.0f, 0.1f, 1.0f,
7104 0.1f, 0.1f, 0.1f, 0.1f,
7105 0.2f, 0.2f, 0.2f, 0.2f,
7106 0.3f, 0.3f, 0.3f, 0.3f,
7107 0.4f, 0.4f, 0.4f, 0.4f,
7108 0.5f, 0.55f, 0.55f, 0.55f,
7109 0.6f, 0.6f, 0.6f, 0.7f,
7110 0.7f, 0.7f, 0.7f, 0.6f,
7111 0.8f, 0.8f, 0.8f, 0.8f,
7112 0xe6e6e6e6, /* 0.9 * 256 */
7113 0x224488ff, /* Nothing special */
7116 640.0f, 480.0f, 0.1f, 1.0f,
7117 0.1f, 0.1f, 0.1f, 0.1f,
7118 0.2f, 0.2f, 0.2f, 0.2f,
7119 0.3f, 0.3f, 0.3f, 0.3f,
7120 0.4f, 0.4f, 0.4f, 0.4f,
7121 0.5f, 0.55f, 0.55f, 0.55f,
7122 0.6f, 0.6f, 0.6f, 0.7f,
7123 0.7f, 0.7f, 0.7f, 0.6f,
7124 0.8f, 0.8f, 0.8f, 0.8f,
7125 0xe6e6e6e6, /* 0.9 * 256 */
7126 0x224488ff, /* Nothing special */
7129 IDirect3DVertexDeclaration9 *decl;
7130 IDirect3DDevice9 *device;
7131 IDirect3D9 *d3d;
7132 unsigned int i;
7133 ULONG refcount;
7134 D3DCAPS9 caps;
7135 DWORD color;
7136 HWND window;
7137 HRESULT hr;
7139 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7140 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7141 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7142 ok(!!d3d, "Failed to create a D3D object.\n");
7143 if (!(device = create_device(d3d, window, window, TRUE)))
7145 skip("Failed to create a D3D device, skipping tests.\n");
7146 goto done;
7149 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7150 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7151 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7153 skip("No shader model 3 support, skipping tests.\n");
7154 IDirect3DDevice9_Release(device);
7155 goto done;
7158 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7160 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7161 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7163 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7165 IDirect3DPixelShader9 *shader;
7167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7168 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7170 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7171 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7173 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7174 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7176 hr = IDirect3DDevice9_BeginScene(device);
7177 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7180 hr = IDirect3DDevice9_EndScene(device);
7181 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7183 /* This isn't a weekend's job to fix, ignore the problem for now.
7184 * Needs a replacement pipeline. */
7185 color = getPixelColor(device, 360, 240);
7186 if (tests[i].todo)
7187 todo_wine ok(color_match(color, tests[i].color, 1)
7188 || broken(color_match(color, 0x00000000, 1)
7189 && tests[i].shader_code == blendindices_code),
7190 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7191 tests[i].name, color, tests[i].color);
7192 else
7193 ok(color_match(color, tests[i].color, 1),
7194 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7195 tests[i].name, color, tests[i].color);
7197 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7198 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7200 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7201 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7202 IDirect3DPixelShader9_Release(shader);
7205 IDirect3DVertexDeclaration9_Release(decl);
7206 refcount = IDirect3DDevice9_Release(device);
7207 ok(!refcount, "Device has %u references left.\n", refcount);
7208 done:
7209 IDirect3D9_Release(d3d);
7210 DestroyWindow(window);
7213 static void test_compare_instructions(void)
7215 IDirect3DVertexShader9 *shader_slt_scalar;
7216 IDirect3DVertexShader9 *shader_sge_scalar;
7217 IDirect3DVertexShader9 *shader_slt_vec;
7218 IDirect3DVertexShader9 *shader_sge_vec;
7219 IDirect3DDevice9 *device;
7220 IDirect3D9 *d3d;
7221 D3DCOLOR color;
7222 ULONG refcount;
7223 D3DCAPS9 caps;
7224 HWND window;
7225 HRESULT hr;
7227 static const DWORD shader_sge_vec_code[] =
7229 0xfffe0101, /* vs_1_1 */
7230 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7231 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7232 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7233 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7234 0x0000ffff /* end */
7236 static const DWORD shader_slt_vec_code[] =
7238 0xfffe0101, /* vs_1_1 */
7239 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7240 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7241 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7242 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7243 0x0000ffff /* end */
7245 static const DWORD shader_sge_scalar_code[] =
7247 0xfffe0101, /* vs_1_1 */
7248 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7249 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7250 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7251 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7252 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7253 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7254 0x0000ffff /* end */
7256 static const DWORD shader_slt_scalar_code[] =
7258 0xfffe0101, /* vs_1_1 */
7259 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7260 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7261 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7262 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7263 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7264 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7265 0x0000ffff /* end */
7267 static const float quad1[] =
7269 -1.0f, -1.0f, 0.1f,
7270 -1.0f, 0.0f, 0.1f,
7271 0.0f, -1.0f, 0.1f,
7272 0.0f, 0.0f, 0.1f,
7274 static const float quad2[] =
7276 0.0f, -1.0f, 0.1f,
7277 0.0f, 0.0f, 0.1f,
7278 1.0f, -1.0f, 0.1f,
7279 1.0f, 0.0f, 0.1f,
7281 static const float quad3[] =
7283 -1.0f, 0.0f, 0.1f,
7284 -1.0f, 1.0f, 0.1f,
7285 0.0f, 0.0f, 0.1f,
7286 0.0f, 1.0f, 0.1f,
7288 static const float quad4[] =
7290 0.0f, 0.0f, 0.1f,
7291 0.0f, 1.0f, 0.1f,
7292 1.0f, 0.0f, 0.1f,
7293 1.0f, 1.0f, 0.1f,
7295 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7296 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7298 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7299 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7300 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7301 ok(!!d3d, "Failed to create a D3D object.\n");
7302 if (!(device = create_device(d3d, window, window, TRUE)))
7304 skip("Failed to create a D3D device, skipping tests.\n");
7305 goto done;
7308 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7309 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7310 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7312 skip("No vs_1_1 support, skipping tests.\n");
7313 IDirect3DDevice9_Release(device);
7314 goto done;
7317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7318 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7320 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7321 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7322 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7323 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7324 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7325 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7326 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7327 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7328 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7329 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7330 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7331 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7332 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7333 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7335 hr = IDirect3DDevice9_BeginScene(device);
7336 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7338 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7339 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7341 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7343 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7344 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7346 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7348 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7349 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7351 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7353 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7354 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7356 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7357 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7359 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7361 hr = IDirect3DDevice9_EndScene(device);
7362 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7364 color = getPixelColor(device, 160, 360);
7365 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7366 color = getPixelColor(device, 480, 360);
7367 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7368 color = getPixelColor(device, 160, 120);
7369 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7370 color = getPixelColor(device, 480, 160);
7371 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7374 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7376 IDirect3DVertexShader9_Release(shader_sge_vec);
7377 IDirect3DVertexShader9_Release(shader_slt_vec);
7378 IDirect3DVertexShader9_Release(shader_sge_scalar);
7379 IDirect3DVertexShader9_Release(shader_slt_scalar);
7380 refcount = IDirect3DDevice9_Release(device);
7381 ok(!refcount, "Device has %u references left.\n", refcount);
7382 done:
7383 IDirect3D9_Release(d3d);
7384 DestroyWindow(window);
7387 static void test_vshader_input(void)
7389 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7390 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7391 IDirect3DVertexDeclaration9 *decl_nocolor;
7392 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7393 D3DADAPTER_IDENTIFIER9 identifier;
7394 IDirect3DPixelShader9 *ps;
7395 IDirect3DDevice9 *device;
7396 IDirect3D9 *d3d;
7397 ULONG refcount;
7398 unsigned int i;
7399 D3DCAPS9 caps;
7400 DWORD color;
7401 HWND window;
7402 HRESULT hr;
7403 BOOL warp;
7405 static const DWORD swapped_shader_code_3[] =
7407 0xfffe0300, /* vs_3_0 */
7408 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7409 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7410 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7411 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7412 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7413 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7414 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7415 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7416 0x0000ffff /* end */
7418 static const DWORD swapped_shader_code_1[] =
7420 0xfffe0101, /* vs_1_1 */
7421 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7422 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7423 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7424 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7425 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7426 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7427 0x0000ffff /* end */
7429 static const DWORD swapped_shader_code_2[] =
7431 0xfffe0200, /* vs_2_0 */
7432 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7433 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7434 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7435 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7436 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7437 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7438 0x0000ffff /* end */
7440 static const DWORD texcoord_color_shader_code_3[] =
7442 0xfffe0300, /* vs_3_0 */
7443 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7444 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7445 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7446 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7447 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7448 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7449 0x0000ffff /* end */
7451 static const DWORD texcoord_color_shader_code_2[] =
7453 0xfffe0200, /* vs_2_0 */
7454 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7455 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7456 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7457 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7458 0x0000ffff /* end */
7460 static const DWORD texcoord_color_shader_code_1[] =
7462 0xfffe0101, /* vs_1_1 */
7463 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7464 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7465 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7466 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7467 0x0000ffff /* end */
7469 static const DWORD color_color_shader_code_3[] =
7471 0xfffe0300, /* vs_3_0 */
7472 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7473 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7474 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7475 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7476 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7477 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7478 0x0000ffff /* end */
7480 static const DWORD color_color_shader_code_2[] =
7482 0xfffe0200, /* vs_2_0 */
7483 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7484 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7485 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7486 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7487 0x0000ffff /* end */
7489 static const DWORD color_color_shader_code_1[] =
7491 0xfffe0101, /* vs_1_1 */
7492 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7493 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7494 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7495 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7496 0x0000ffff /* end */
7498 static const DWORD ps3_code[] =
7500 0xffff0300, /* ps_3_0 */
7501 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7502 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7503 0x0000ffff /* end */
7505 static const float quad1[] =
7507 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7508 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7509 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7510 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7512 static const float quad2[] =
7514 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7515 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7516 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7517 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7519 static const float quad3[] =
7521 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7522 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7523 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7524 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7526 static const float quad4[] =
7528 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7529 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7530 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7531 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7533 static const float quad1_modified[] =
7535 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7536 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7537 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7538 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7540 static const float quad2_modified[] =
7542 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7543 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7544 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7545 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7547 static const struct
7549 struct vec3 position;
7550 DWORD diffuse;
7552 quad1_color[] =
7554 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7555 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7556 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7557 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7559 quad2_color[] =
7561 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7562 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7563 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7564 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7566 quad3_color[] =
7568 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7569 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7570 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7571 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7573 static const float quad4_color[] =
7575 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7576 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7577 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7578 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7580 static const struct vec3 quad_nocolor[] =
7582 {-1.0f, -1.0f, 0.1f},
7583 {-1.0f, 1.0f, 0.1f},
7584 { 1.0f, -1.0f, 0.1f},
7585 { 1.0f, 1.0f, 0.1f},
7587 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7589 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7590 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7591 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7592 D3DDECL_END()
7594 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7596 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7597 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7598 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7599 D3DDECL_END()
7601 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7603 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7604 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7605 D3DDECL_END()
7607 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7609 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7610 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7611 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7612 D3DDECL_END()
7614 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7616 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7617 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7618 D3DDECL_END()
7620 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7622 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7623 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7624 D3DDECL_END()
7626 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7628 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7629 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7630 D3DDECL_END()
7632 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7634 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7635 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7636 D3DDECL_END()
7638 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7640 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7641 D3DDECL_END()
7643 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7644 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7646 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7647 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7648 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7649 ok(!!d3d, "Failed to create a D3D object.\n");
7650 if (!(device = create_device(d3d, window, window, TRUE)))
7652 skip("Failed to create a D3D device, skipping tests.\n");
7653 goto done;
7656 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7657 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7658 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7660 skip("No vs_3_0 support, skipping tests.\n");
7661 IDirect3DDevice9_Release(device);
7662 goto done;
7665 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7666 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7667 warp = !strcmp(identifier.Description, "Microsoft Basic Render Driver");
7669 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7670 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7671 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7672 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7673 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7675 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7676 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7678 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7679 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7680 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7682 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7683 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7684 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7685 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7686 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7687 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7689 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7690 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7692 for (i = 1; i <= 3; ++i)
7694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7695 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7696 if(i == 3) {
7697 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7698 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7699 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7700 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7701 } else if(i == 2){
7702 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7703 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7704 } else if(i == 1) {
7705 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7706 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7709 hr = IDirect3DDevice9_BeginScene(device);
7710 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7712 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7713 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7715 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7716 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7718 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7720 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7721 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7723 if (i == 3 || i == 2)
7724 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7725 else if (i == 1)
7726 /* Succeeds or fails, depending on SW or HW vertex processing. */
7727 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7729 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7730 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7732 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7734 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7735 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7737 if (i == 3 || i == 2)
7738 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7739 else if (i == 1)
7740 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7742 hr = IDirect3DDevice9_EndScene(device);
7743 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7745 if(i == 3 || i == 2) {
7746 color = getPixelColor(device, 160, 360);
7747 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7748 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7750 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7751 color = getPixelColor(device, 480, 360);
7752 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7753 * mostly random data as input. */
7754 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7755 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7756 color = getPixelColor(device, 160, 120);
7757 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7758 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7759 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7761 color = getPixelColor(device, 480, 160);
7762 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7763 } else if(i == 1) {
7764 color = getPixelColor(device, 160, 360);
7765 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7766 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7767 color = getPixelColor(device, 480, 360);
7768 /* Accept the clear color as well in this case, since SW VP
7769 * returns an error. On the Windows 8 testbot (WARP) the draw
7770 * succeeds, but uses mostly random data as input. */
7771 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7772 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7773 color = getPixelColor(device, 160, 120);
7774 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7775 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7776 color = getPixelColor(device, 480, 160);
7777 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7780 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7781 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7783 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7784 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7786 /* Now find out if the whole streams are re-read, or just the last
7787 * active value for the vertices is used. */
7788 hr = IDirect3DDevice9_BeginScene(device);
7789 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7791 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7792 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7794 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7795 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7797 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7799 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7800 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7802 if (i == 3 || i == 2)
7803 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7804 else if (i == 1)
7805 /* Succeeds or fails, depending on SW or HW vertex processing. */
7806 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7808 hr = IDirect3DDevice9_EndScene(device);
7809 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7811 color = getPixelColor(device, 480, 350);
7812 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7813 * as well.
7815 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7816 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7817 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7818 * refrast's result.
7820 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7822 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7823 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7824 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7827 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7829 IDirect3DDevice9_SetVertexShader(device, NULL);
7830 IDirect3DDevice9_SetPixelShader(device, NULL);
7831 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7833 IDirect3DVertexShader9_Release(swapped_shader);
7836 for (i = 1; i <= 3; ++i)
7838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7839 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7840 if(i == 3) {
7841 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
7842 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7843 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
7844 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7845 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7846 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7847 } else if(i == 2){
7848 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
7849 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7850 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
7851 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7852 } else if(i == 1) {
7853 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
7854 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7855 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
7856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7859 hr = IDirect3DDevice9_BeginScene(device);
7860 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7862 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
7863 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7864 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
7865 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7867 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7869 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
7870 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7872 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
7873 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7874 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
7875 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7877 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7879 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
7880 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7881 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
7882 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7884 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7886 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
7887 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7889 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7891 hr = IDirect3DDevice9_EndScene(device);
7892 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7894 color = getPixelColor(device, 160, 360);
7895 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7896 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7897 color = getPixelColor(device, 480, 360);
7898 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7899 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7900 color = getPixelColor(device, 160, 120);
7901 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7902 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7903 color = getPixelColor(device, 480, 160);
7904 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7905 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7907 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7910 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
7911 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7914 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7916 hr = IDirect3DDevice9_BeginScene(device);
7917 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
7919 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7920 hr = IDirect3DDevice9_EndScene(device);
7921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7923 /* WARP ends up using the color attribute from the previous draw. Let's mark
7924 * that behavior as broken. */
7925 color = getPixelColor(device, 160, 360);
7926 ok(color_match(color, 0x00000000, 1)
7927 || broken(color_match(color, 0x00ffff00, 1)),
7928 "Got unexpected color 0x%08x for no color attribute test.\n", color);
7930 IDirect3DDevice9_SetVertexShader(device, NULL);
7931 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7932 IDirect3DDevice9_SetPixelShader(device, NULL);
7934 IDirect3DVertexShader9_Release(texcoord_color_shader);
7935 IDirect3DVertexShader9_Release(color_color_shader);
7938 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
7939 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
7940 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
7941 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
7943 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
7944 IDirect3DVertexDeclaration9_Release(decl_color_color);
7945 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
7946 IDirect3DVertexDeclaration9_Release(decl_color_float);
7947 IDirect3DVertexDeclaration9_Release(decl_nocolor);
7949 IDirect3DPixelShader9_Release(ps);
7950 refcount = IDirect3DDevice9_Release(device);
7951 ok(!refcount, "Device has %u references left.\n", refcount);
7952 done:
7953 IDirect3D9_Release(d3d);
7954 DestroyWindow(window);
7957 static void srgbtexture_test(void)
7959 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
7960 * texture stage state to render a quad using that texture. The resulting
7961 * color components should be 0x36 (~ 0.21), per this formula:
7962 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
7963 * This is true where srgb_color > 0.04045. */
7964 struct IDirect3DTexture9 *texture;
7965 struct IDirect3DSurface9 *surface;
7966 IDirect3DDevice9 *device;
7967 IDirect3D9 *d3d;
7968 D3DCOLOR color;
7969 ULONG refcount;
7970 HWND window;
7971 HRESULT hr;
7973 static const float quad[] =
7975 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
7976 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7977 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
7978 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
7981 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7982 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7983 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7984 ok(!!d3d, "Failed to create a D3D object.\n");
7985 if (!(device = create_device(d3d, window, window, TRUE)))
7987 skip("Failed to create a D3D device, skipping tests.\n");
7988 goto done;
7991 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
7992 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
7994 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
7995 IDirect3DDevice9_Release(device);
7996 goto done;
7999 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8000 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8001 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8002 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8004 fill_surface(surface, 0xff7f7f7f, 0);
8005 IDirect3DSurface9_Release(surface);
8007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8008 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8009 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8010 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8012 hr = IDirect3DDevice9_BeginScene(device);
8013 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8015 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8016 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8017 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8018 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8019 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8020 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8022 hr = IDirect3DDevice9_EndScene(device);
8023 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8025 color = getPixelColor(device, 320, 240);
8026 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8028 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8029 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8031 IDirect3DTexture9_Release(texture);
8032 refcount = IDirect3DDevice9_Release(device);
8033 ok(!refcount, "Device has %u references left.\n", refcount);
8034 done:
8035 IDirect3D9_Release(d3d);
8036 DestroyWindow(window);
8039 static void shademode_test(void)
8041 /* Render a quad and try all of the different fixed function shading models. */
8042 DWORD color0_gouraud = 0, color1_gouraud = 0;
8043 DWORD primtype = D3DPT_TRIANGLESTRIP;
8044 IDirect3DVertexBuffer9 *vb_strip;
8045 IDirect3DVertexBuffer9 *vb_list;
8046 DWORD shademode = D3DSHADE_FLAT;
8047 IDirect3DDevice9 *device;
8048 DWORD color0, color1;
8049 void *data = NULL;
8050 IDirect3D9 *d3d;
8051 ULONG refcount;
8052 HWND window;
8053 HRESULT hr;
8054 UINT i, j;
8056 static const struct
8058 struct vec3 position;
8059 DWORD diffuse;
8061 quad_strip[] =
8063 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8064 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8065 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8066 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8068 quad_list[] =
8070 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8071 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8072 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8074 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8075 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8076 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8079 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8080 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8081 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8082 ok(!!d3d, "Failed to create a D3D object.\n");
8083 if (!(device = create_device(d3d, window, window, TRUE)))
8085 skip("Failed to create a D3D device, skipping tests.\n");
8086 goto done;
8089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8090 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8093 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8095 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8096 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8097 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8098 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8099 memcpy(data, quad_strip, sizeof(quad_strip));
8100 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8101 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8103 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8104 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8105 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8106 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8107 memcpy(data, quad_list, sizeof(quad_list));
8108 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8109 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8111 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8112 * the color fixups we have to do for FLAT shading will be dependent on that. */
8113 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
8114 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8116 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
8117 for (j=0; j<2; j++) {
8119 /* Inner loop just changes the D3DRS_SHADEMODE */
8120 for (i=0; i<3; i++) {
8121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8122 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127 hr = IDirect3DDevice9_BeginScene(device);
8128 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8129 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
8130 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8131 hr = IDirect3DDevice9_EndScene(device);
8132 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8134 /* Sample two spots from the output */
8135 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8136 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8137 switch(shademode) {
8138 case D3DSHADE_FLAT:
8139 /* Should take the color of the first vertex of each triangle */
8140 if (0)
8142 /* This test depends on EXT_provoking_vertex being
8143 * available. This extension is currently (20090810)
8144 * not common enough to let the test fail if it isn't
8145 * present. */
8146 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
8147 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
8149 shademode = D3DSHADE_GOURAUD;
8150 break;
8151 case D3DSHADE_GOURAUD:
8152 /* Should be an interpolated blend */
8154 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
8155 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
8156 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
8157 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
8159 color0_gouraud = color0;
8160 color1_gouraud = color1;
8162 shademode = D3DSHADE_PHONG;
8163 break;
8164 case D3DSHADE_PHONG:
8165 /* Should be the same as GOURAUD, since no hardware implements this */
8166 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
8167 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
8168 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
8169 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
8171 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
8172 color0_gouraud, color0);
8173 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
8174 color1_gouraud, color1);
8175 break;
8179 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8180 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8182 /* Now, do it all over again with a TRIANGLELIST */
8183 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
8184 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8185 primtype = D3DPT_TRIANGLELIST;
8186 shademode = D3DSHADE_FLAT;
8189 IDirect3DVertexBuffer9_Release(vb_strip);
8190 IDirect3DVertexBuffer9_Release(vb_list);
8191 refcount = IDirect3DDevice9_Release(device);
8192 ok(!refcount, "Device has %u references left.\n", refcount);
8193 done:
8194 IDirect3D9_Release(d3d);
8195 DestroyWindow(window);
8198 static void test_blend(void)
8200 IDirect3DSurface9 *backbuffer, *offscreen;
8201 IDirect3DTexture9 *offscreenTexture;
8202 IDirect3DDevice9 *device;
8203 IDirect3D9 *d3d;
8204 D3DCOLOR color;
8205 ULONG refcount;
8206 HWND window;
8207 HRESULT hr;
8209 static const struct
8211 struct vec3 position;
8212 DWORD diffuse;
8214 quad1[] =
8216 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8217 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8218 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8219 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8221 quad2[] =
8223 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8224 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8225 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8226 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8228 static const float composite_quad[][5] =
8230 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8231 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8232 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8233 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8236 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8237 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8238 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8239 ok(!!d3d, "Failed to create a D3D object.\n");
8240 if (!(device = create_device(d3d, window, window, TRUE)))
8242 skip("Failed to create a D3D device, skipping tests.\n");
8243 goto done;
8246 /* Clear the render target with alpha = 0.5 */
8247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8248 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8250 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8251 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8252 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8254 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8255 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8257 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8258 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8260 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8263 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8264 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8265 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8266 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8268 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8269 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8270 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8276 hr = IDirect3DDevice9_BeginScene(device);
8277 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8279 /* Draw two quads, one with src alpha blending, one with dest alpha
8280 * blending. */
8281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8282 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8284 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8286 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8289 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8291 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8293 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8295 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8296 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8297 * "don't work" on render targets without alpha channel, they give
8298 * essentially ZERO and ONE blend factors. */
8299 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8300 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8301 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8302 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8305 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8307 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8308 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8309 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8312 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8314 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8315 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8316 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8318 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8319 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8321 /* Render the offscreen texture onto the frame buffer to be able to
8322 * compare it regularly. Disable alpha blending for the final
8323 * composition. */
8324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8325 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8326 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8327 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8329 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8330 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8332 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8334 hr = IDirect3DDevice9_EndScene(device);
8335 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8337 color = getPixelColor(device, 160, 360);
8338 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8339 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8341 color = getPixelColor(device, 160, 120);
8342 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8343 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8345 color = getPixelColor(device, 480, 360);
8346 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8347 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8349 color = getPixelColor(device, 480, 120);
8350 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8351 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8353 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8355 IDirect3DSurface9_Release(backbuffer);
8356 IDirect3DTexture9_Release(offscreenTexture);
8357 IDirect3DSurface9_Release(offscreen);
8358 refcount = IDirect3DDevice9_Release(device);
8359 ok(!refcount, "Device has %u references left.\n", refcount);
8360 done:
8361 IDirect3D9_Release(d3d);
8362 DestroyWindow(window);
8365 static void fixed_function_decl_test(void)
8367 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8368 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
8369 IDirect3DVertexBuffer9 *vb, *vb2;
8370 IDirect3DDevice9 *device;
8371 BOOL s_ok, ub_ok, f_ok;
8372 DWORD color, size, i;
8373 IDirect3D9 *d3d;
8374 ULONG refcount;
8375 D3DCAPS9 caps;
8376 HWND window;
8377 void *data;
8378 HRESULT hr;
8380 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8381 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8382 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8383 D3DDECL_END()
8385 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8386 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8387 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8388 D3DDECL_END()
8390 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8391 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8392 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8393 D3DDECL_END()
8395 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8396 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8397 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8398 D3DDECL_END()
8400 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8401 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8402 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8403 D3DDECL_END()
8405 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8406 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8407 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8408 D3DDECL_END()
8410 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8411 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8412 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8413 D3DDECL_END()
8415 static const struct
8417 struct vec3 position;
8418 DWORD diffuse;
8420 quad1[] = /* D3DCOLOR */
8422 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8423 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8424 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8425 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8427 quad2[] = /* UBYTE4N */
8429 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8430 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8431 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8432 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8434 static const struct
8436 struct vec3 position;
8437 struct { unsigned short x, y, z, w; } color;
8439 quad3[] = /* USHORT4N */
8441 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8442 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8443 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8444 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8446 static const struct
8448 struct vec3 position;
8449 struct vec4 color;
8451 quad4[] =
8453 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8454 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8455 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8456 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8458 static const DWORD colors[] =
8460 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8461 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8462 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8463 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8464 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8465 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8466 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8467 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8468 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8469 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8470 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8471 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8472 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8473 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8474 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8475 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8477 static const float quads[] =
8479 -1.0f, -1.0f, 0.1f,
8480 -1.0f, 0.0f, 0.1f,
8481 0.0f, -1.0f, 0.1f,
8482 0.0f, 0.0f, 0.1f,
8484 0.0f, -1.0f, 0.1f,
8485 0.0f, 0.0f, 0.1f,
8486 1.0f, -1.0f, 0.1f,
8487 1.0f, 0.0f, 0.1f,
8489 0.0f, 0.0f, 0.1f,
8490 0.0f, 1.0f, 0.1f,
8491 1.0f, 0.0f, 0.1f,
8492 1.0f, 1.0f, 0.1f,
8494 -1.0f, 0.0f, 0.1f,
8495 -1.0f, 1.0f, 0.1f,
8496 0.0f, 0.0f, 0.1f,
8497 0.0f, 1.0f, 0.1f,
8499 static const struct
8501 struct vec4 position;
8502 DWORD diffuse;
8504 quad_transformed[] =
8506 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8507 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8508 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8509 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8512 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8513 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8514 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8515 ok(!!d3d, "Failed to create a D3D object.\n");
8516 if (!(device = create_device(d3d, window, window, TRUE)))
8518 skip("Failed to create a D3D device, skipping tests.\n");
8519 goto done;
8522 memset(&caps, 0, sizeof(caps));
8523 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8524 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8527 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8529 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8530 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8531 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8532 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8533 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8534 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8535 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8536 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8537 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8538 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8539 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8540 } else {
8541 trace("D3DDTCAPS_UBYTE4N not supported\n");
8542 dcl_ubyte_2 = NULL;
8543 dcl_ubyte = NULL;
8545 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8546 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8547 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8548 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8550 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8551 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8552 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8553 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8556 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8558 hr = IDirect3DDevice9_BeginScene(device);
8559 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8561 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8562 if (dcl_color)
8564 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8565 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8567 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8570 /* Tests with non-standard fixed function types fail on the refrast. The
8571 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8572 * All those differences even though we're using software vertex
8573 * processing. Doh! */
8574 if (dcl_ubyte)
8576 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8577 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8579 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8580 ub_ok = SUCCEEDED(hr);
8583 if (dcl_short)
8585 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8586 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8588 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8589 s_ok = SUCCEEDED(hr);
8592 if (dcl_float)
8594 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8595 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8597 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8598 f_ok = SUCCEEDED(hr);
8601 hr = IDirect3DDevice9_EndScene(device);
8602 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8604 if(dcl_short) {
8605 color = getPixelColor(device, 480, 360);
8606 ok(color == 0x000000ff || !s_ok,
8607 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8609 if(dcl_ubyte) {
8610 color = getPixelColor(device, 160, 120);
8611 ok(color == 0x0000ffff || !ub_ok,
8612 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8614 if(dcl_color) {
8615 color = getPixelColor(device, 160, 360);
8616 ok(color == 0x00ffff00,
8617 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8619 if(dcl_float) {
8620 color = getPixelColor(device, 480, 120);
8621 ok(color == 0x00ff0000 || !f_ok,
8622 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8624 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8626 /* The following test with vertex buffers doesn't serve to find out new
8627 * information from windows. It is a plain regression test because wined3d
8628 * uses different codepaths for attribute conversion with vertex buffers.
8629 * It makes sure that the vertex buffer one works, while the above tests
8630 * whether the immediate mode code works. */
8631 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8632 hr = IDirect3DDevice9_BeginScene(device);
8633 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8635 if (dcl_color)
8637 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8638 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8639 memcpy(data, quad1, sizeof(quad1));
8640 hr = IDirect3DVertexBuffer9_Unlock(vb);
8641 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8642 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8643 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8644 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8645 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8646 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8647 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8650 if (dcl_ubyte)
8652 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8653 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8654 memcpy(data, quad2, sizeof(quad2));
8655 hr = IDirect3DVertexBuffer9_Unlock(vb);
8656 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8657 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8658 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8659 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8660 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8661 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8662 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8663 ub_ok = SUCCEEDED(hr);
8666 if (dcl_short)
8668 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8669 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8670 memcpy(data, quad3, sizeof(quad3));
8671 hr = IDirect3DVertexBuffer9_Unlock(vb);
8672 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8673 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8674 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8675 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8676 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8677 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8678 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8679 s_ok = SUCCEEDED(hr);
8682 if (dcl_float)
8684 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8685 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8686 memcpy(data, quad4, sizeof(quad4));
8687 hr = IDirect3DVertexBuffer9_Unlock(vb);
8688 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8689 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8690 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8691 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8692 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8693 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8694 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8695 f_ok = SUCCEEDED(hr);
8698 hr = IDirect3DDevice9_EndScene(device);
8699 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8701 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8702 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8703 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8704 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8706 if(dcl_short) {
8707 color = getPixelColor(device, 480, 360);
8708 ok(color == 0x000000ff || !s_ok,
8709 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8711 if(dcl_ubyte) {
8712 color = getPixelColor(device, 160, 120);
8713 ok(color == 0x0000ffff || !ub_ok,
8714 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8716 if(dcl_color) {
8717 color = getPixelColor(device, 160, 360);
8718 ok(color == 0x00ffff00,
8719 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8721 if(dcl_float) {
8722 color = getPixelColor(device, 480, 120);
8723 ok(color == 0x00ff0000 || !f_ok,
8724 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8726 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8728 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8729 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8731 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
8732 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8733 memcpy(data, quad_transformed, sizeof(quad_transformed));
8734 hr = IDirect3DVertexBuffer9_Unlock(vb);
8735 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8737 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
8738 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8740 hr = IDirect3DDevice9_BeginScene(device);
8741 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8742 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
8743 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8744 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8745 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8746 hr = IDirect3DDevice9_EndScene(device);
8747 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8749 color = getPixelColor(device, 88, 108);
8750 ok(color == 0x000000ff,
8751 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8752 color = getPixelColor(device, 92, 108);
8753 ok(color == 0x000000ff,
8754 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8755 color = getPixelColor(device, 88, 112);
8756 ok(color == 0x000000ff,
8757 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8758 color = getPixelColor(device, 92, 112);
8759 ok(color == 0x00ffff00,
8760 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8762 color = getPixelColor(device, 568, 108);
8763 ok(color == 0x000000ff,
8764 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8765 color = getPixelColor(device, 572, 108);
8766 ok(color == 0x000000ff,
8767 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8768 color = getPixelColor(device, 568, 112);
8769 ok(color == 0x00ffff00,
8770 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8771 color = getPixelColor(device, 572, 112);
8772 ok(color == 0x000000ff,
8773 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8775 color = getPixelColor(device, 88, 298);
8776 ok(color == 0x000000ff,
8777 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8778 color = getPixelColor(device, 92, 298);
8779 ok(color == 0x00ffff00,
8780 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8781 color = getPixelColor(device, 88, 302);
8782 ok(color == 0x000000ff,
8783 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8784 color = getPixelColor(device, 92, 302);
8785 ok(color == 0x000000ff,
8786 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8788 color = getPixelColor(device, 568, 298);
8789 ok(color == 0x00ffff00,
8790 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8791 color = getPixelColor(device, 572, 298);
8792 ok(color == 0x000000ff,
8793 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8794 color = getPixelColor(device, 568, 302);
8795 ok(color == 0x000000ff,
8796 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8797 color = getPixelColor(device, 572, 302);
8798 ok(color == 0x000000ff,
8799 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8801 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8803 /* This test is pointless without those two declarations: */
8804 if((!dcl_color_2) || (!dcl_ubyte_2)) {
8805 skip("color-ubyte switching test declarations aren't supported\n");
8806 goto out;
8809 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
8810 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8811 memcpy(data, quads, sizeof(quads));
8812 hr = IDirect3DVertexBuffer9_Unlock(vb);
8813 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8814 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
8815 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8816 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8817 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
8818 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8819 memcpy(data, colors, sizeof(colors));
8820 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8821 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8823 for(i = 0; i < 2; i++) {
8824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8825 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8827 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
8828 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8829 if(i == 0) {
8830 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
8831 } else {
8832 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
8834 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8836 hr = IDirect3DDevice9_BeginScene(device);
8837 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8839 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8840 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8841 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8842 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8843 ub_ok = SUCCEEDED(hr);
8845 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
8846 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8847 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8848 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8850 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8851 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8852 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8853 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8854 ub_ok = (SUCCEEDED(hr) && ub_ok);
8856 hr = IDirect3DDevice9_EndScene(device);
8857 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8859 if(i == 0) {
8860 color = getPixelColor(device, 480, 360);
8861 ok(color == 0x00ff0000,
8862 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
8863 color = getPixelColor(device, 160, 120);
8864 ok(color == 0x00ffffff,
8865 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8866 color = getPixelColor(device, 160, 360);
8867 ok(color == 0x000000ff || !ub_ok,
8868 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8869 color = getPixelColor(device, 480, 120);
8870 ok(color == 0x000000ff || !ub_ok,
8871 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8872 } else {
8873 color = getPixelColor(device, 480, 360);
8874 ok(color == 0x000000ff,
8875 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
8876 color = getPixelColor(device, 160, 120);
8877 ok(color == 0x00ffffff,
8878 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8879 color = getPixelColor(device, 160, 360);
8880 ok(color == 0x00ff0000 || !ub_ok,
8881 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8882 color = getPixelColor(device, 480, 120);
8883 ok(color == 0x00ff0000 || !ub_ok,
8884 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8886 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8889 IDirect3DVertexBuffer9_Release(vb2);
8890 out:
8891 IDirect3DVertexBuffer9_Release(vb);
8892 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
8893 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
8894 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
8895 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
8896 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
8897 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
8898 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
8899 refcount = IDirect3DDevice9_Release(device);
8900 ok(!refcount, "Device has %u references left.\n", refcount);
8901 done:
8902 IDirect3D9_Release(d3d);
8903 DestroyWindow(window);
8906 static void test_vshader_float16(void)
8908 IDirect3DVertexDeclaration9 *vdecl = NULL;
8909 IDirect3DVertexBuffer9 *buffer = NULL;
8910 IDirect3DVertexShader9 *shader;
8911 IDirect3DDevice9 *device;
8912 IDirect3D9 *d3d;
8913 ULONG refcount;
8914 D3DCAPS9 caps;
8915 DWORD color;
8916 HWND window;
8917 void *data;
8918 HRESULT hr;
8920 static const D3DVERTEXELEMENT9 decl_elements[] =
8922 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8923 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8924 D3DDECL_END()
8926 static const DWORD shader_code[] =
8928 0xfffe0101, /* vs_1_1 */
8929 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8930 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8931 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8932 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8933 0x0000ffff,
8935 static const struct vertex_float16color
8937 float x, y, z;
8938 DWORD c1, c2;
8940 quad[] =
8942 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
8943 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8944 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
8945 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8947 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
8948 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8949 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
8950 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8952 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
8953 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8954 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
8955 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8957 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
8958 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8959 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
8960 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8963 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8964 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8965 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8966 ok(!!d3d, "Failed to create a D3D object.\n");
8967 if (!(device = create_device(d3d, window, window, TRUE)))
8969 skip("Failed to create a D3D device, skipping tests.\n");
8970 goto done;
8973 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8974 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8975 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8977 skip("No vs_3_0 support, skipping tests.\n");
8978 IDirect3DDevice9_Release(device);
8979 goto done;
8982 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
8983 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8985 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
8986 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
8987 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8988 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8989 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8990 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8992 hr = IDirect3DDevice9_BeginScene(device);
8993 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8994 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
8995 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
8997 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
8999 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9003 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9004 hr = IDirect3DDevice9_EndScene(device);
9005 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9007 color = getPixelColor(device, 480, 360);
9008 ok(color == 0x00ff0000,
9009 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9010 color = getPixelColor(device, 160, 120);
9011 ok(color == 0x00000000,
9012 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9013 color = getPixelColor(device, 160, 360);
9014 ok(color == 0x0000ff00,
9015 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9016 color = getPixelColor(device, 480, 120);
9017 ok(color == 0x000000ff,
9018 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9019 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9021 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9022 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9024 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9025 D3DPOOL_MANAGED, &buffer, NULL);
9026 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9027 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9028 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9029 memcpy(data, quad, sizeof(quad));
9030 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9031 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9032 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9033 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9035 hr = IDirect3DDevice9_BeginScene(device);
9036 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9037 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9038 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9039 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9041 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9042 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9043 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9044 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9045 hr = IDirect3DDevice9_EndScene(device);
9046 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9048 color = getPixelColor(device, 480, 360);
9049 ok(color == 0x00ff0000,
9050 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9051 color = getPixelColor(device, 160, 120);
9052 ok(color == 0x00000000,
9053 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9054 color = getPixelColor(device, 160, 360);
9055 ok(color == 0x0000ff00,
9056 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9057 color = getPixelColor(device, 480, 120);
9058 ok(color == 0x000000ff,
9059 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9060 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9062 IDirect3DVertexDeclaration9_Release(vdecl);
9063 IDirect3DVertexShader9_Release(shader);
9064 IDirect3DVertexBuffer9_Release(buffer);
9065 refcount = IDirect3DDevice9_Release(device);
9066 ok(!refcount, "Device has %u references left.\n", refcount);
9067 done:
9068 IDirect3D9_Release(d3d);
9069 DestroyWindow(window);
9072 static void conditional_np2_repeat_test(void)
9074 IDirect3DTexture9 *texture;
9075 IDirect3DDevice9 *device;
9076 D3DLOCKED_RECT rect;
9077 unsigned int x, y;
9078 DWORD *dst, color;
9079 IDirect3D9 *d3d;
9080 ULONG refcount;
9081 D3DCAPS9 caps;
9082 HWND window;
9083 HRESULT hr;
9085 static const float quad[] =
9087 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9088 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9089 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9090 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9093 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9094 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9095 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9096 ok(!!d3d, "Failed to create a D3D object.\n");
9097 if (!(device = create_device(d3d, window, window, TRUE)))
9099 skip("Failed to create a D3D device, skipping tests.\n");
9100 goto done;
9103 memset(&caps, 0, sizeof(caps));
9104 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9105 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9106 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9108 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9109 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9110 "Card has conditional NP2 support without power of two restriction set\n");
9112 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9114 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9115 IDirect3DDevice9_Release(device);
9116 goto done;
9118 else
9120 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9121 IDirect3DDevice9_Release(device);
9122 goto done;
9125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9126 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9128 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9129 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9131 memset(&rect, 0, sizeof(rect));
9132 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9133 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9134 for(y = 0; y < 10; y++) {
9135 for(x = 0; x < 10; x++) {
9136 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9137 if(x == 0 || x == 9 || y == 0 || y == 9) {
9138 *dst = 0x00ff0000;
9139 } else {
9140 *dst = 0x000000ff;
9144 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9145 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9147 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9148 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9150 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9152 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9153 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9154 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9155 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9158 hr = IDirect3DDevice9_BeginScene(device);
9159 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9161 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9162 hr = IDirect3DDevice9_EndScene(device);
9163 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9165 color = getPixelColor(device, 1, 1);
9166 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9167 color = getPixelColor(device, 639, 479);
9168 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9170 color = getPixelColor(device, 135, 101);
9171 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9172 color = getPixelColor(device, 140, 101);
9173 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9174 color = getPixelColor(device, 135, 105);
9175 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9176 color = getPixelColor(device, 140, 105);
9177 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9179 color = getPixelColor(device, 135, 376);
9180 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9181 color = getPixelColor(device, 140, 376);
9182 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9183 color = getPixelColor(device, 135, 379);
9184 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9185 color = getPixelColor(device, 140, 379);
9186 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9188 color = getPixelColor(device, 500, 101);
9189 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9190 color = getPixelColor(device, 504, 101);
9191 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9192 color = getPixelColor(device, 500, 105);
9193 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9194 color = getPixelColor(device, 504, 105);
9195 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9197 color = getPixelColor(device, 500, 376);
9198 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9199 color = getPixelColor(device, 504, 376);
9200 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9201 color = getPixelColor(device, 500, 380);
9202 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9203 color = getPixelColor(device, 504, 380);
9204 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9206 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9208 IDirect3DTexture9_Release(texture);
9209 refcount = IDirect3DDevice9_Release(device);
9210 ok(!refcount, "Device has %u references left.\n", refcount);
9211 done:
9212 IDirect3D9_Release(d3d);
9213 DestroyWindow(window);
9216 static void vface_register_test(void)
9218 IDirect3DSurface9 *surface, *backbuffer;
9219 IDirect3DVertexShader9 *vshader;
9220 IDirect3DPixelShader9 *shader;
9221 IDirect3DTexture9 *texture;
9222 IDirect3DDevice9 *device;
9223 IDirect3D9 *d3d;
9224 ULONG refcount;
9225 D3DCAPS9 caps;
9226 DWORD color;
9227 HWND window;
9228 HRESULT hr;
9230 static const DWORD shader_code[] =
9232 0xffff0300, /* ps_3_0 */
9233 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9234 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9235 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9236 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9237 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9238 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9239 0x0000ffff /* END */
9241 static const DWORD vshader_code[] =
9243 0xfffe0300, /* vs_3_0 */
9244 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9245 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9246 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9247 0x0000ffff /* end */
9249 static const float quad[] =
9251 -1.0f, -1.0f, 0.1f,
9252 1.0f, -1.0f, 0.1f,
9253 -1.0f, 0.0f, 0.1f,
9255 1.0f, -1.0f, 0.1f,
9256 1.0f, 0.0f, 0.1f,
9257 -1.0f, 0.0f, 0.1f,
9259 -1.0f, 0.0f, 0.1f,
9260 -1.0f, 1.0f, 0.1f,
9261 1.0f, 0.0f, 0.1f,
9263 1.0f, 0.0f, 0.1f,
9264 -1.0f, 1.0f, 0.1f,
9265 1.0f, 1.0f, 0.1f,
9267 static const float blit[] =
9269 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9270 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9271 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9272 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9275 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9276 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9277 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9278 ok(!!d3d, "Failed to create a D3D object.\n");
9279 if (!(device = create_device(d3d, window, window, TRUE)))
9281 skip("Failed to create a D3D device, skipping tests.\n");
9282 goto done;
9285 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9286 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9287 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9289 skip("No shader model 3 support, skipping tests.\n");
9290 IDirect3DDevice9_Release(device);
9291 goto done;
9294 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9295 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9296 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9297 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9298 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9299 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9300 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9301 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9303 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9304 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9305 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9306 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9307 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9308 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9309 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9310 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9311 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9314 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9316 hr = IDirect3DDevice9_BeginScene(device);
9317 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9319 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9320 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9321 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9322 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9323 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9325 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9326 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9327 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9329 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9331 /* Blit the texture onto the back buffer to make it visible */
9332 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9333 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9334 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9335 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9336 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9337 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9338 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9339 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9340 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9341 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9342 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9343 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9345 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9347 hr = IDirect3DDevice9_EndScene(device);
9348 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9350 color = getPixelColor(device, 160, 360);
9351 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9352 color = getPixelColor(device, 160, 120);
9353 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9354 color = getPixelColor(device, 480, 360);
9355 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9356 color = getPixelColor(device, 480, 120);
9357 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9359 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9361 IDirect3DPixelShader9_Release(shader);
9362 IDirect3DVertexShader9_Release(vshader);
9363 IDirect3DSurface9_Release(surface);
9364 IDirect3DSurface9_Release(backbuffer);
9365 IDirect3DTexture9_Release(texture);
9366 refcount = IDirect3DDevice9_Release(device);
9367 ok(!refcount, "Device has %u references left.\n", refcount);
9368 done:
9369 IDirect3D9_Release(d3d);
9370 DestroyWindow(window);
9373 static void fixed_function_bumpmap_test(void)
9375 IDirect3DVertexDeclaration9 *vertex_declaration;
9376 IDirect3DTexture9 *texture, *tex1, *tex2;
9377 D3DLOCKED_RECT locked_rect;
9378 IDirect3DDevice9 *device;
9379 BOOL L6V5U5_supported;
9380 float scale, offset;
9381 IDirect3D9 *d3d;
9382 unsigned int i;
9383 D3DCOLOR color;
9384 ULONG refcount;
9385 D3DCAPS9 caps;
9386 HWND window;
9387 HRESULT hr;
9389 static const float quad[][7] =
9391 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9392 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9393 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9394 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9396 static const D3DVERTEXELEMENT9 decl_elements[] =
9398 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9399 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9400 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9401 D3DDECL_END()
9403 /* use asymmetric matrix to test loading */
9404 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9406 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9407 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9408 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9409 ok(!!d3d, "Failed to create a D3D object.\n");
9410 if (!(device = create_device(d3d, window, window, TRUE)))
9412 skip("Failed to create a D3D device, skipping tests.\n");
9413 goto done;
9416 memset(&caps, 0, sizeof(caps));
9417 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9418 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9419 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9421 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9422 IDirect3DDevice9_Release(device);
9423 goto done;
9426 /* This check is disabled, some Windows drivers do not handle
9427 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9428 * supported, but after that bump mapping works properly. So just test if
9429 * the format is generally supported, and check the BUMPENVMAP flag. */
9430 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9431 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9432 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9433 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9435 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9436 IDirect3DDevice9_Release(device);
9437 return;
9440 /* Generate the textures */
9441 generate_bumpmap_textures(device);
9443 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9444 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9445 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9446 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9447 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9448 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9449 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9450 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9452 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9453 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9454 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9455 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9456 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9457 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9459 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9460 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9461 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9462 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9463 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9464 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9466 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9467 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9469 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9470 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9473 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9475 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9476 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9477 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9478 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9480 hr = IDirect3DDevice9_BeginScene(device);
9481 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9484 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9486 hr = IDirect3DDevice9_EndScene(device);
9487 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9489 color = getPixelColor(device, 240, 60);
9490 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9491 color = getPixelColor(device, 400, 60);
9492 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9493 color = getPixelColor(device, 80, 180);
9494 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9495 color = getPixelColor(device, 560, 180);
9496 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9497 color = getPixelColor(device, 80, 300);
9498 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9499 color = getPixelColor(device, 560, 300);
9500 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9501 color = getPixelColor(device, 240, 420);
9502 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9503 color = getPixelColor(device, 400, 420);
9504 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9505 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9506 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9508 for(i = 0; i < 2; i++) {
9509 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9510 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9511 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9512 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9513 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9514 IDirect3DTexture9_Release(texture); /* To destroy it */
9517 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9519 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9520 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9521 IDirect3DDevice9_Release(device);
9522 goto done;
9525 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9526 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9527 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9528 * would only make this test more complicated
9530 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9531 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9532 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9533 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9535 memset(&locked_rect, 0, sizeof(locked_rect));
9536 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9537 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9538 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9539 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9540 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9542 memset(&locked_rect, 0, sizeof(locked_rect));
9543 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9544 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9545 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9546 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9547 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9549 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9550 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9551 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9552 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9554 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9555 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9556 scale = 2.0;
9557 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9558 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9559 offset = 0.1;
9560 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9561 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9563 hr = IDirect3DDevice9_BeginScene(device);
9564 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9566 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9567 hr = IDirect3DDevice9_EndScene(device);
9568 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9570 color = getPixelColor(device, 320, 240);
9571 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9572 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9573 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9575 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9577 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9579 /* Check a result scale factor > 1.0 */
9580 scale = 10;
9581 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9582 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9583 offset = 10;
9584 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9585 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9587 hr = IDirect3DDevice9_BeginScene(device);
9588 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9590 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9591 hr = IDirect3DDevice9_EndScene(device);
9592 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9594 color = getPixelColor(device, 320, 240);
9595 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9597 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9599 /* Check clamping in the scale factor calculation */
9600 scale = 1000;
9601 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9602 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9603 offset = -1;
9604 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9605 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9607 hr = IDirect3DDevice9_BeginScene(device);
9608 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9610 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9611 hr = IDirect3DDevice9_EndScene(device);
9612 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9614 color = getPixelColor(device, 320, 240);
9615 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9616 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9617 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9619 IDirect3DTexture9_Release(tex1);
9620 IDirect3DTexture9_Release(tex2);
9621 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9622 refcount = IDirect3DDevice9_Release(device);
9623 ok(!refcount, "Device has %u references left.\n", refcount);
9624 done:
9625 IDirect3D9_Release(d3d);
9626 DestroyWindow(window);
9629 static void stencil_cull_test(void)
9631 IDirect3DDevice9 *device;
9632 IDirect3D9 *d3d;
9633 ULONG refcount;
9634 D3DCAPS9 caps;
9635 HWND window;
9636 HRESULT hr;
9637 static const float quad1[] =
9639 -1.0, -1.0, 0.1,
9640 0.0, -1.0, 0.1,
9641 -1.0, 0.0, 0.1,
9642 0.0, 0.0, 0.1,
9644 static const float quad2[] =
9646 0.0, -1.0, 0.1,
9647 1.0, -1.0, 0.1,
9648 0.0, 0.0, 0.1,
9649 1.0, 0.0, 0.1,
9651 static const float quad3[] =
9653 0.0, 0.0, 0.1,
9654 1.0, 0.0, 0.1,
9655 0.0, 1.0, 0.1,
9656 1.0, 1.0, 0.1,
9658 static const float quad4[] =
9660 -1.0, 0.0, 0.1,
9661 0.0, 0.0, 0.1,
9662 -1.0, 1.0, 0.1,
9663 0.0, 1.0, 0.1,
9665 struct
9667 struct vec3 position;
9668 DWORD diffuse;
9670 painter[] =
9672 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
9673 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
9674 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
9675 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
9677 static const WORD indices_cw[] = {0, 1, 3};
9678 static const WORD indices_ccw[] = {0, 2, 3};
9679 unsigned int i;
9680 DWORD color;
9682 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9683 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9684 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9685 ok(!!d3d, "Failed to create a D3D object.\n");
9686 if (!(device = create_device(d3d, window, window, TRUE)))
9688 skip("Cannot create a device with a D24S8 stencil buffer.\n");
9689 DestroyWindow(window);
9690 IDirect3D9_Release(d3d);
9691 return;
9693 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9694 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9695 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
9697 skip("No two sided stencil support\n");
9698 goto cleanup;
9701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
9702 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9703 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9704 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
9706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9707 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
9708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9709 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
9710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
9711 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
9713 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9714 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
9715 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
9717 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
9720 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
9722 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
9724 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9726 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
9727 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9729 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9731 /* First pass: Fill the stencil buffer with some values... */
9732 hr = IDirect3DDevice9_BeginScene(device);
9733 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9736 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9737 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9738 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9739 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9740 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9741 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9742 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
9745 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9747 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9748 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9749 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9750 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9751 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9752 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9753 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9755 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9756 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9757 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9758 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9759 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9760 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9761 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9762 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
9765 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9766 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9767 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9768 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9769 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9770 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9771 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9773 hr = IDirect3DDevice9_EndScene(device);
9774 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
9777 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9778 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
9779 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
9781 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9783 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9785 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
9787 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9789 /* 2nd pass: Make the stencil values visible */
9790 hr = IDirect3DDevice9_BeginScene(device);
9791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9792 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9793 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9794 for (i = 0; i < 16; ++i)
9796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
9797 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9799 painter[0].diffuse = (i * 16); /* Creates shades of blue */
9800 painter[1].diffuse = (i * 16);
9801 painter[2].diffuse = (i * 16);
9802 painter[3].diffuse = (i * 16);
9803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
9804 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9806 hr = IDirect3DDevice9_EndScene(device);
9807 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9810 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9812 color = getPixelColor(device, 160, 420);
9813 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
9814 color = getPixelColor(device, 160, 300);
9815 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9817 color = getPixelColor(device, 480, 420);
9818 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
9819 color = getPixelColor(device, 480, 300);
9820 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
9822 color = getPixelColor(device, 160, 180);
9823 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
9824 color = getPixelColor(device, 160, 60);
9825 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
9827 color = getPixelColor(device, 480, 180);
9828 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
9829 color = getPixelColor(device, 480, 60);
9830 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9832 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9833 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9835 cleanup:
9836 refcount = IDirect3DDevice9_Release(device);
9837 ok(!refcount, "Device has %u references left.\n", refcount);
9838 IDirect3D9_Release(d3d);
9839 DestroyWindow(window);
9842 static void test_fragment_coords(void)
9844 IDirect3DSurface9 *surface = NULL, *backbuffer;
9845 IDirect3DPixelShader9 *shader, *shader_frac;
9846 IDirect3DVertexShader9 *vshader;
9847 IDirect3DDevice9 *device;
9848 D3DLOCKED_RECT lr;
9849 IDirect3D9 *d3d;
9850 ULONG refcount;
9851 D3DCAPS9 caps;
9852 DWORD color;
9853 HWND window;
9854 HRESULT hr;
9855 DWORD *pos;
9857 static const DWORD shader_code[] =
9859 0xffff0300, /* ps_3_0 */
9860 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9861 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
9862 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
9863 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
9864 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
9865 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
9866 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
9867 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
9868 0x0000ffff /* end */
9870 static const DWORD shader_frac_code[] =
9872 0xffff0300, /* ps_3_0 */
9873 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
9874 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9875 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
9876 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
9877 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9878 0x0000ffff /* end */
9880 static const DWORD vshader_code[] =
9882 0xfffe0300, /* vs_3_0 */
9883 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9884 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9885 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9886 0x0000ffff /* end */
9888 static const float quad[] =
9890 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9891 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9892 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9893 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9895 float constant[4] = {1.0, 0.0, 320, 240};
9897 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9898 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9899 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9900 ok(!!d3d, "Failed to create a D3D object.\n");
9901 if (!(device = create_device(d3d, window, window, TRUE)))
9903 skip("Failed to create a D3D device, skipping tests.\n");
9904 goto done;
9907 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9908 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9909 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9911 skip("No shader model 3 support, skipping tests.\n");
9912 IDirect3DDevice9_Release(device);
9913 goto done;
9916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9917 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9918 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9919 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9920 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9921 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9922 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
9923 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9924 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9925 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9926 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9927 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9928 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9929 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9930 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9931 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9933 hr = IDirect3DDevice9_BeginScene(device);
9934 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9935 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9936 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9938 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9939 hr = IDirect3DDevice9_EndScene(device);
9940 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9942 /* This has to be pixel exact */
9943 color = getPixelColor(device, 319, 239);
9944 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
9945 color = getPixelColor(device, 320, 239);
9946 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
9947 color = getPixelColor(device, 319, 240);
9948 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
9949 color = getPixelColor(device, 320, 240);
9950 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
9951 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9953 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
9954 &surface, NULL);
9955 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
9956 hr = IDirect3DDevice9_BeginScene(device);
9957 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9958 constant[2] = 16; constant[3] = 16;
9959 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9960 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9961 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9962 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9964 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9965 hr = IDirect3DDevice9_EndScene(device);
9966 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9968 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9969 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9971 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9972 color = *pos & 0x00ffffff;
9973 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
9974 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
9975 color = *pos & 0x00ffffff;
9976 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
9977 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
9978 color = *pos & 0x00ffffff;
9979 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
9980 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
9981 color = *pos & 0x00ffffff;
9982 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
9984 hr = IDirect3DSurface9_UnlockRect(surface);
9985 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9987 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
9988 * have full control over the multisampling setting inside this test
9990 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
9991 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9992 hr = IDirect3DDevice9_BeginScene(device);
9993 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9994 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9995 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9997 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9998 hr = IDirect3DDevice9_EndScene(device);
9999 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10001 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10002 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10004 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10005 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10007 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10008 color = *pos & 0x00ffffff;
10009 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10011 hr = IDirect3DSurface9_UnlockRect(surface);
10012 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10014 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10015 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10016 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10017 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10018 IDirect3DPixelShader9_Release(shader);
10019 IDirect3DPixelShader9_Release(shader_frac);
10020 IDirect3DVertexShader9_Release(vshader);
10021 if(surface) IDirect3DSurface9_Release(surface);
10022 IDirect3DSurface9_Release(backbuffer);
10023 refcount = IDirect3DDevice9_Release(device);
10024 ok(!refcount, "Device has %u references left.\n", refcount);
10025 done:
10026 IDirect3D9_Release(d3d);
10027 DestroyWindow(window);
10030 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10032 D3DCOLOR color;
10034 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10035 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10036 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10037 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10038 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10040 ++r;
10041 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10042 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10043 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10044 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10045 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10047 return TRUE;
10050 static void pointsize_test(void)
10052 static const float a = 0.5f, b = 0.5f, c = 0.5f;
10053 float ptsize, ptsizemax_orig, ptsizemin_orig;
10054 IDirect3DSurface9 *rt, *backbuffer;
10055 IDirect3DTexture9 *tex1, *tex2;
10056 IDirect3DDevice9 *device;
10057 IDirect3DVertexShader9 *vs;
10058 IDirect3DPixelShader9 *ps;
10059 D3DLOCKED_RECT lr;
10060 IDirect3D9 *d3d;
10061 D3DCOLOR color;
10062 ULONG refcount;
10063 D3DCAPS9 caps;
10064 HWND window;
10065 HRESULT hr;
10066 unsigned int i, j;
10068 static const RECT rect = {0, 0, 128, 128};
10069 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10070 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10071 static const float vertices[] =
10073 64.0f, 64.0f, 0.1f,
10074 128.0f, 64.0f, 0.1f,
10075 192.0f, 64.0f, 0.1f,
10076 256.0f, 64.0f, 0.1f,
10077 320.0f, 64.0f, 0.1f,
10078 384.0f, 64.0f, 0.1f,
10079 448.0f, 64.0f, 0.1f,
10080 512.0f, 64.0f, 0.1f,
10082 static const struct
10084 float x, y, z;
10085 float point_size;
10087 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10088 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10089 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10090 static const DWORD vshader_code[] =
10092 0xfffe0101, /* vs_1_1 */
10093 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10094 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10095 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10096 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10097 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10098 0x0000ffff
10100 static const DWORD vshader_psize_code[] =
10102 0xfffe0101, /* vs_1_1 */
10103 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10104 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10105 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10106 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10107 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10108 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10109 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10110 0x0000ffff
10112 static const DWORD pshader_code[] =
10114 0xffff0101, /* ps_1_1 */
10115 0x00000042, 0xb00f0000, /* tex t0 */
10116 0x00000042, 0xb00f0001, /* tex t1 */
10117 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10118 0x0000ffff
10120 static const DWORD pshader2_code[] =
10122 0xffff0200, /* ps_2_0 */
10123 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10124 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10125 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10126 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10127 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10128 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10129 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10130 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10131 0x0000ffff
10133 static const DWORD pshader2_zw_code[] =
10135 0xffff0200, /* ps_2_0 */
10136 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10137 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10138 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10139 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10140 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10141 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10142 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10143 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10144 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10145 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10146 0x0000ffff
10148 static const DWORD vshader3_code[] =
10150 0xfffe0300, /* vs_3_0 */
10151 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10152 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10153 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10154 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10155 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10156 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10157 0x0000ffff
10159 static const DWORD vshader3_psize_code[] =
10161 0xfffe0300, /* vs_3_0 */
10162 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10163 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10164 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10165 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10166 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10167 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10168 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10169 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10170 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10171 0x0000ffff
10173 static const DWORD pshader3_code[] =
10175 0xffff0300, /* ps_3_0 */
10176 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10177 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10178 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10179 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10180 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10181 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10182 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10183 0x0000ffff
10185 static const DWORD pshader3_zw_code[] =
10187 0xffff0300, /* ps_3_0 */
10188 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10189 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10190 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10191 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10192 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10193 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10194 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10195 0x0000ffff
10197 static const struct test_shader
10199 DWORD version;
10200 const DWORD *code;
10202 novs = {0, NULL},
10203 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10204 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10205 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10206 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10207 nops = {0, NULL},
10208 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10209 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10210 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10211 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10212 ps3_zw = {D3DVS_VERSION(3, 0), pshader3_zw_code};
10213 static const struct
10215 const struct test_shader *vs;
10216 const struct test_shader *ps;
10217 DWORD accepted_fvf;
10218 unsigned int nonscaled_size, scaled_size;
10219 BOOL gives_0_0_texcoord;
10220 BOOL allow_broken;
10222 test_setups[] =
10224 {&novs, &nops, D3DFVF_XYZ, 32, 62, FALSE, FALSE},
10225 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10226 {&novs, &ps1, D3DFVF_XYZ, 32, 62, FALSE, FALSE},
10227 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10228 {&novs, &ps2, D3DFVF_XYZ, 32, 62, FALSE, TRUE},
10229 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 62, TRUE, FALSE},
10230 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10231 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10232 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10233 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10234 /* {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48, FALSE, FALSE}, */
10235 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10236 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10238 static const struct
10240 BOOL zero_size;
10241 BOOL scale;
10242 BOOL override_min;
10243 DWORD fvf;
10244 const void *vertex_data;
10245 unsigned int vertex_size;
10247 tests[] =
10249 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10250 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10251 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10252 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10253 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10254 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10255 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10256 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10258 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10259 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10260 D3DMATRIX matrix =
10262 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10263 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10264 0.0f, 0.0f, 1.0f, 0.0f,
10265 -1.0f, 1.0f, 0.0f, 1.0f,
10266 }}};
10268 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10269 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10270 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10271 ok(!!d3d, "Failed to create a D3D object.\n");
10272 if (!(device = create_device(d3d, window, window, TRUE)))
10274 skip("Failed to create a D3D device, skipping tests.\n");
10275 goto done;
10278 memset(&caps, 0, sizeof(caps));
10279 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10280 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10281 if(caps.MaxPointSize < 32.0) {
10282 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10283 IDirect3DDevice9_Release(device);
10284 goto done;
10287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10288 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10290 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10291 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10292 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10293 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10294 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10296 hr = IDirect3DDevice9_BeginScene(device);
10297 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10299 ptsize = 15.0f;
10300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10301 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10303 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10305 ptsize = 31.0f;
10306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10307 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10308 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10309 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10311 ptsize = 30.75f;
10312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10313 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10315 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10317 if (caps.MaxPointSize >= 63.0f)
10319 ptsize = 63.0f;
10320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10321 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10322 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10323 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10325 ptsize = 62.75f;
10326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10327 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10328 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10329 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10332 ptsize = 1.0f;
10333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10334 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10336 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10338 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10339 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10340 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10341 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10343 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10344 ptsize = 15.0f;
10345 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10346 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10347 ptsize = 1.0f;
10348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10349 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10351 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10354 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10356 /* pointsize < pointsize_min < pointsize_max?
10357 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10358 ptsize = 1.0f;
10359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10360 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10361 ptsize = 15.0f;
10362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10363 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10365 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10368 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10370 hr = IDirect3DDevice9_EndScene(device);
10371 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10373 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10374 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10375 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10377 if (caps.MaxPointSize >= 63.0)
10379 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10380 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10383 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10384 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10385 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10386 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10387 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10389 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10391 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10392 * generates texture coordinates for the point(result: Yes, it does)
10394 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10395 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10396 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10401 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10402 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10403 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10404 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10405 memset(&lr, 0, sizeof(lr));
10406 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10407 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10408 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10409 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10410 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10411 memset(&lr, 0, sizeof(lr));
10412 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10413 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10414 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10415 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10416 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10417 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10418 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10419 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10421 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10422 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10423 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10424 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10425 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10426 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10427 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10428 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10429 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10430 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10433 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10434 ptsize = 32.0;
10435 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10436 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10438 hr = IDirect3DDevice9_BeginScene(device);
10439 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10441 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10442 hr = IDirect3DDevice9_EndScene(device);
10443 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10445 color = getPixelColor(device, 64-4, 64-4);
10446 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10447 color = getPixelColor(device, 64-4, 64+4);
10448 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10449 color = getPixelColor(device, 64+4, 64+4);
10450 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10451 color = getPixelColor(device, 64+4, 64-4);
10452 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10453 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10455 U(matrix).m[0][0] = 1.0f / 64.0f;
10456 U(matrix).m[1][1] = -1.0f / 64.0f;
10457 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10458 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10460 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10461 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10463 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10464 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10465 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10467 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10468 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10470 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10471 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10472 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10473 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10474 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10476 if (caps.MaxPointSize < 63.0f)
10478 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10479 goto cleanup;
10482 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10484 if (caps.VertexShaderVersion < test_setups[i].vs->version
10485 || caps.PixelShaderVersion < test_setups[i].ps->version)
10487 skip("Vertex / pixel shader version not supported, skipping test.\n");
10488 continue;
10490 if (test_setups[i].vs->code)
10492 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10493 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10495 else
10497 vs = NULL;
10499 if (test_setups[i].ps->code)
10501 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10502 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10504 else
10506 ps = NULL;
10509 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10510 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10511 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10512 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10514 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10516 BOOL allow_broken = test_setups[i].allow_broken;
10517 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10518 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10520 if (test_setups[i].accepted_fvf != tests[j].fvf)
10521 continue;
10523 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10525 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10527 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10529 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10532 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10534 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10535 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10537 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10538 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10539 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10540 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10542 hr = IDirect3DDevice9_BeginScene(device);
10543 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10545 tests[j].vertex_data, tests[j].vertex_size);
10546 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10547 hr = IDirect3DDevice9_EndScene(device);
10548 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10550 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10551 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10552 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10553 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10555 if (tests[j].zero_size)
10557 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10558 * it does the "useful" thing on all the drivers I tried. */
10559 /* On WARP it does draw some pixels, most of the time. */
10560 color = getPixelColor(device, 64, 64);
10561 ok(color_match(color, 0x0000ffff, 0)
10562 || broken(color_match(color, 0x00ff0000, 0))
10563 || broken(color_match(color, 0x00ffff00, 0))
10564 || broken(color_match(color, 0x00000000, 0))
10565 || broken(color_match(color, 0x0000ff00, 0)),
10566 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10568 else
10570 /* On AMD apparently only the first texcoord is modified by the point coordinates
10571 * when using SM2/3 pixel shaders. */
10572 color = getPixelColor(device, 64 - size / 2 + 1, 64 - size / 2 + 1);
10573 ok(color_match(color, 0x00ff0000, 0),
10574 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10575 color = getPixelColor(device, 64 + size / 2 - 1, 64 - size / 2 + 1);
10576 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10577 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10578 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10579 color = getPixelColor(device, 64 - size / 2 + 1, 64 + size / 2 - 1);
10580 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10581 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10582 color = getPixelColor(device, 64 + size / 2 - 1, 64 + size / 2 - 1);
10583 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10584 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10585 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10587 color = getPixelColor(device, 64 - size / 2 - 1, 64 - size / 2 - 1);
10588 ok(color_match(color, 0x0000ffff, 0),
10589 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10590 color = getPixelColor(device, 64 + size / 2 + 1, 64 - size / 2 - 1);
10591 ok(color_match(color, 0x0000ffff, 0),
10592 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10593 color = getPixelColor(device, 64 - size / 2 - 1, 64 + size / 2 + 1);
10594 ok(color_match(color, 0x0000ffff, 0),
10595 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10596 color = getPixelColor(device, 64 + size / 2 + 1, 64 + size / 2 + 1);
10597 ok(color_match(color, 0x0000ffff, 0),
10598 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10601 IDirect3DDevice9_SetVertexShader(device, NULL);
10602 IDirect3DDevice9_SetPixelShader(device, NULL);
10603 if (vs)
10604 IDirect3DVertexShader9_Release(vs);
10605 if (ps)
10606 IDirect3DVertexShader9_Release(ps);
10609 cleanup:
10610 IDirect3DSurface9_Release(backbuffer);
10611 IDirect3DSurface9_Release(rt);
10613 IDirect3DTexture9_Release(tex1);
10614 IDirect3DTexture9_Release(tex2);
10615 refcount = IDirect3DDevice9_Release(device);
10616 ok(!refcount, "Device has %u references left.\n", refcount);
10617 done:
10618 IDirect3D9_Release(d3d);
10619 DestroyWindow(window);
10622 static void multiple_rendertargets_test(void)
10624 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
10625 IDirect3DPixelShader9 *ps1, *ps2;
10626 IDirect3DTexture9 *tex1, *tex2;
10627 IDirect3DVertexShader9 *vs;
10628 IDirect3DDevice9 *device;
10629 IDirect3D9 *d3d;
10630 ULONG refcount;
10631 D3DCAPS9 caps;
10632 DWORD color;
10633 HWND window;
10634 HRESULT hr;
10635 UINT i, j;
10637 static const DWORD vshader_code[] =
10639 0xfffe0300, /* vs_3_0 */
10640 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10641 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10642 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10643 0x0000ffff /* end */
10645 static const DWORD pshader_code1[] =
10647 0xffff0300, /* ps_3_0 */
10648 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10649 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10650 0x0000ffff /* end */
10652 static const DWORD pshader_code2[] =
10654 0xffff0300, /* ps_3_0 */
10655 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10656 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
10657 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10658 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
10659 0x0000ffff /* end */
10661 static const float quad[] =
10663 -1.0f, -1.0f, 0.1f,
10664 -1.0f, 1.0f, 0.1f,
10665 1.0f, -1.0f, 0.1f,
10666 1.0f, 1.0f, 0.1f,
10668 static const float texquad[] =
10670 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10671 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10672 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10673 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10675 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10676 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10677 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10678 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10681 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10682 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10683 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10684 ok(!!d3d, "Failed to create a D3D object.\n");
10685 if (!(device = create_device(d3d, window, window, TRUE)))
10687 skip("Failed to create a D3D device, skipping tests.\n");
10688 goto done;
10691 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10692 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10693 if (caps.NumSimultaneousRTs < 2)
10695 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
10696 IDirect3DDevice9_Release(device);
10697 goto done;
10699 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10701 skip("No shader model 3 support, skipping tests.\n");
10702 IDirect3DDevice9_Release(device);
10703 goto done;
10706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
10707 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10709 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
10710 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
10711 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
10713 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10714 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
10715 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10716 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10717 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
10718 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10719 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
10720 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
10721 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
10722 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10723 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
10724 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10726 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
10727 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
10728 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
10729 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10730 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
10731 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10733 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10734 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10735 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
10736 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10737 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
10738 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10739 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10740 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10742 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10743 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10744 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10745 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10746 color = getPixelColorFromSurface(readback, 8, 8);
10747 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10748 "Expected color 0x000000ff, got 0x%08x.\n", color);
10749 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10750 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10751 color = getPixelColorFromSurface(readback, 8, 8);
10752 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10753 "Expected color 0x000000ff, got 0x%08x.\n", color);
10755 /* Render targets not written by the pixel shader should be unmodified. */
10756 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
10757 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10758 hr = IDirect3DDevice9_BeginScene(device);
10759 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10761 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10762 hr = IDirect3DDevice9_EndScene(device);
10763 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10764 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10765 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10766 color = getPixelColorFromSurface(readback, 8, 8);
10767 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10768 "Expected color 0xff00ff00, got 0x%08x.\n", color);
10769 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10770 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10771 for (i = 6; i < 10; ++i)
10773 for (j = 6; j < 10; ++j)
10775 color = getPixelColorFromSurface(readback, j, i);
10776 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10777 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
10781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
10782 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10783 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10784 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10785 color = getPixelColorFromSurface(readback, 8, 8);
10786 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10787 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10788 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10789 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10790 color = getPixelColorFromSurface(readback, 8, 8);
10791 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10792 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10794 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
10795 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10797 hr = IDirect3DDevice9_BeginScene(device);
10798 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10801 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10804 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10805 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10806 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10807 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10808 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10809 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
10810 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10811 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
10812 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10813 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10814 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10816 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10817 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
10819 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10821 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
10822 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
10824 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10826 hr = IDirect3DDevice9_EndScene(device);
10827 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10829 color = getPixelColor(device, 160, 240);
10830 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
10831 color = getPixelColor(device, 480, 240);
10832 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
10833 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10835 IDirect3DPixelShader9_Release(ps2);
10836 IDirect3DPixelShader9_Release(ps1);
10837 IDirect3DVertexShader9_Release(vs);
10838 IDirect3DTexture9_Release(tex1);
10839 IDirect3DTexture9_Release(tex2);
10840 IDirect3DSurface9_Release(surf1);
10841 IDirect3DSurface9_Release(surf2);
10842 IDirect3DSurface9_Release(backbuf);
10843 IDirect3DSurface9_Release(readback);
10844 refcount = IDirect3DDevice9_Release(device);
10845 ok(!refcount, "Device has %u references left.\n", refcount);
10846 done:
10847 IDirect3D9_Release(d3d);
10848 DestroyWindow(window);
10851 static void pixelshader_blending_test(void)
10853 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
10854 IDirect3DTexture9 *offscreenTexture = NULL;
10855 IDirect3DDevice9 *device;
10856 IDirect3D9 *d3d;
10857 ULONG refcount;
10858 int fmt_index;
10859 DWORD color;
10860 HWND window;
10861 HRESULT hr;
10863 static const struct
10865 const char *fmtName;
10866 D3DFORMAT textureFormat;
10867 D3DCOLOR resultColorBlending;
10868 D3DCOLOR resultColorNoBlending;
10870 test_formats[] =
10872 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
10873 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
10874 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff},
10875 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000},
10876 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
10877 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff},
10878 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000},
10880 static const float quad[][5] =
10882 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
10883 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
10884 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
10885 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
10887 static const struct
10889 struct vec3 position;
10890 DWORD diffuse;
10892 /* Quad with R=0x10, G=0x20 */
10893 quad1[] =
10895 {{-1.0f, -1.0f, 0.1f}, 0x80102000},
10896 {{-1.0f, 1.0f, 0.1f}, 0x80102000},
10897 {{ 1.0f, -1.0f, 0.1f}, 0x80102000},
10898 {{ 1.0f, 1.0f, 0.1f}, 0x80102000},
10900 /* Quad with R=0x20, G=0x10 */
10901 quad2[] =
10903 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
10904 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
10905 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
10906 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
10909 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10910 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10911 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10912 ok(!!d3d, "Failed to create a D3D object.\n");
10913 if (!(device = create_device(d3d, window, window, TRUE)))
10915 skip("Failed to create a D3D device, skipping tests.\n");
10916 goto done;
10919 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10920 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
10922 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
10924 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
10926 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10927 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
10929 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
10930 continue;
10933 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10934 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
10936 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
10937 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
10938 if(!offscreenTexture) {
10939 continue;
10942 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
10943 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
10944 if(!offscreen) {
10945 continue;
10948 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10949 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
10951 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10952 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10954 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10955 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10956 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
10957 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10958 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
10959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10962 /* Below we will draw two quads with different colors and try to blend
10963 * them together. The result color is compared with the expected
10964 * outcome. */
10965 hr = IDirect3DDevice9_BeginScene(device);
10966 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10968 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
10969 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
10971 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
10974 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10976 /* Draw a quad using color 0x0010200. */
10977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
10978 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
10980 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10982 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10984 /* Draw a quad using color 0x0020100. */
10985 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
10986 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
10988 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10990 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10992 /* We don't want to blend the result on the backbuffer. */
10993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
10994 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10996 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
10997 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10998 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10999 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11000 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11002 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11003 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11005 /* This time with the texture. */
11006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11009 hr = IDirect3DDevice9_EndScene(device);
11010 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11012 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11013 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11015 /* Compare the color of the center quad with our expectation. */
11016 color = getPixelColor(device, 320, 240);
11017 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11018 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11019 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11021 else
11023 /* No pixel shader blending is supported so expect garbage. The
11024 * type of 'garbage' depends on the driver version and OS. E.g. on
11025 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11026 * modern ones 0x002010ff which is also what NVIDIA reports. On
11027 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11028 color = getPixelColor(device, 320, 240);
11029 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11030 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11031 test_formats[fmt_index].fmtName, color);
11033 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11035 IDirect3DDevice9_SetTexture(device, 0, NULL);
11036 if(offscreenTexture) {
11037 IDirect3DTexture9_Release(offscreenTexture);
11039 if(offscreen) {
11040 IDirect3DSurface9_Release(offscreen);
11044 IDirect3DSurface9_Release(backbuffer);
11045 refcount = IDirect3DDevice9_Release(device);
11046 ok(!refcount, "Device has %u references left.\n", refcount);
11047 done:
11048 IDirect3D9_Release(d3d);
11049 DestroyWindow(window);
11052 static void tssargtemp_test(void)
11054 IDirect3DDevice9 *device;
11055 IDirect3D9 *d3d;
11056 D3DCOLOR color;
11057 ULONG refcount;
11058 D3DCAPS9 caps;
11059 HWND window;
11060 HRESULT hr;
11062 static const struct
11064 struct vec3 position;
11065 DWORD diffuse;
11067 quad[] =
11069 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11070 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11071 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11072 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11075 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11076 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11077 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11078 ok(!!d3d, "Failed to create a D3D object.\n");
11079 if (!(device = create_device(d3d, window, window, TRUE)))
11081 skip("Failed to create a D3D device, skipping tests.\n");
11082 goto done;
11085 memset(&caps, 0, sizeof(caps));
11086 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11087 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11088 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11089 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11090 IDirect3DDevice9_Release(device);
11091 goto done;
11094 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11095 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11097 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11098 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11099 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11100 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11102 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11103 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11104 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11105 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11106 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11107 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11109 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11110 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11111 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11112 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11113 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11114 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11116 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11117 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11120 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11122 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11123 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11124 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11126 hr = IDirect3DDevice9_BeginScene(device);
11127 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11129 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11130 hr = IDirect3DDevice9_EndScene(device);
11131 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11133 color = getPixelColor(device, 320, 240);
11134 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11135 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11137 refcount = IDirect3DDevice9_Release(device);
11138 ok(!refcount, "Device has %u references left.\n", refcount);
11139 done:
11140 IDirect3D9_Release(d3d);
11141 DestroyWindow(window);
11144 /* Drawing Indexed Geometry with instances*/
11145 static void stream_test(void)
11147 IDirect3DVertexDeclaration9 *pDecl = NULL;
11148 IDirect3DVertexShader9 *shader = NULL;
11149 IDirect3DVertexBuffer9 *vb3 = NULL;
11150 IDirect3DVertexBuffer9 *vb2 = NULL;
11151 IDirect3DVertexBuffer9 *vb = NULL;
11152 IDirect3DIndexBuffer9 *ib = NULL;
11153 IDirect3DDevice9 *device;
11154 IDirect3D9 *d3d;
11155 ULONG refcount;
11156 D3DCAPS9 caps;
11157 DWORD color;
11158 HWND window;
11159 unsigned i;
11160 HRESULT hr;
11161 BYTE *data;
11162 DWORD ind;
11164 static const struct testdata
11166 DWORD idxVertex; /* number of instances in the first stream */
11167 DWORD idxColor; /* number of instances in the second stream */
11168 DWORD idxInstance; /* should be 1 ?? */
11169 DWORD color1; /* color 1 instance */
11170 DWORD color2; /* color 2 instance */
11171 DWORD color3; /* color 3 instance */
11172 DWORD color4; /* color 4 instance */
11173 WORD strVertex; /* specify which stream to use 0-2*/
11174 WORD strColor;
11175 WORD strInstance;
11177 testcases[]=
11179 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11180 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11181 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11182 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11183 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11184 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11185 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11186 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11187 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11188 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11189 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11190 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11191 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11192 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11193 #if 0
11194 /* This draws one instance on some machines, no instance on others. */
11195 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11196 /* This case is handled in a stand alone test,
11197 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11198 * return D3DERR_INVALIDCALL. */
11199 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11200 #endif
11202 static const DWORD shader_code[] =
11204 0xfffe0101, /* vs_1_1 */
11205 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11206 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11207 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11208 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11209 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11210 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11211 0x0000ffff
11213 static const float quad[][3] =
11215 {-0.5f, -0.5f, 1.1f}, /*0 */
11216 {-0.5f, 0.5f, 1.1f}, /*1 */
11217 { 0.5f, -0.5f, 1.1f}, /*2 */
11218 { 0.5f, 0.5f, 1.1f}, /*3 */
11220 static const float vertcolor[][4] =
11222 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11223 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11224 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11225 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11227 /* 4 position for 4 instances */
11228 static const float instancepos[][3] =
11230 {-0.6f,-0.6f, 0.0f},
11231 { 0.6f,-0.6f, 0.0f},
11232 { 0.6f, 0.6f, 0.0f},
11233 {-0.6f, 0.6f, 0.0f},
11235 static const short indices[] = {0, 1, 2, 2, 1, 3};
11236 D3DVERTEXELEMENT9 decl[] =
11238 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11239 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11240 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11241 D3DDECL_END()
11244 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11245 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11246 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11247 ok(!!d3d, "Failed to create a D3D object.\n");
11248 if (!(device = create_device(d3d, window, window, TRUE)))
11250 skip("Failed to create a D3D device, skipping tests.\n");
11251 goto done;
11254 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11255 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11256 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11258 skip("No vs_3_0 support, skipping tests.\n");
11259 IDirect3DDevice9_Release(device);
11260 goto done;
11263 /* set the default value because it isn't done in wine? */
11264 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11265 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11267 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11268 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11269 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11271 /* check wrong cases */
11272 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11273 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11274 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11275 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11276 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11277 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11278 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11279 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11280 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11281 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11282 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11283 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11284 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11285 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11286 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11287 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11288 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11289 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11290 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11291 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11293 /* set the default value back */
11294 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11295 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11297 /* create all VertexBuffers*/
11298 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11299 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11300 if(!vb) {
11301 skip("Failed to create a vertex buffer\n");
11302 IDirect3DDevice9_Release(device);
11303 goto done;
11305 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11306 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11307 if(!vb2) {
11308 skip("Failed to create a vertex buffer\n");
11309 goto out;
11311 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11312 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11313 if(!vb3) {
11314 skip("Failed to create a vertex buffer\n");
11315 goto out;
11318 /* create IndexBuffer*/
11319 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11320 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11321 if(!ib) {
11322 skip("Failed to create an index buffer\n");
11323 goto out;
11326 /* copy all Buffers (Vertex + Index)*/
11327 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11328 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11329 memcpy(data, quad, sizeof(quad));
11330 hr = IDirect3DVertexBuffer9_Unlock(vb);
11331 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11332 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11333 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11334 memcpy(data, vertcolor, sizeof(vertcolor));
11335 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11336 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11337 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11338 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11339 memcpy(data, instancepos, sizeof(instancepos));
11340 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11341 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11342 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11343 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11344 memcpy(data, indices, sizeof(indices));
11345 hr = IDirect3DIndexBuffer9_Unlock(ib);
11346 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11348 /* create VertexShader */
11349 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11350 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11351 if(!shader) {
11352 skip("Failed to create a vetex shader\n");
11353 goto out;
11356 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11357 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11359 hr = IDirect3DDevice9_SetIndices(device, ib);
11360 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11362 /* run all tests */
11363 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11365 struct testdata act = testcases[i];
11366 decl[0].Stream = act.strVertex;
11367 decl[1].Stream = act.strColor;
11368 decl[2].Stream = act.strInstance;
11369 /* create VertexDeclarations */
11370 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11371 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11374 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11376 hr = IDirect3DDevice9_BeginScene(device);
11377 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11379 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11380 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11382 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11383 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11384 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11385 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11386 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11388 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11389 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11390 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11391 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11392 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11394 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11395 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11396 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11397 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11398 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11400 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11401 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11402 hr = IDirect3DDevice9_EndScene(device);
11403 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11405 /* set all StreamSource && StreamSourceFreq back to default */
11406 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11407 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11408 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11409 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11410 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11411 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11412 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11413 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11414 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11415 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11416 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11417 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11419 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11420 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11422 color = getPixelColor(device, 160, 360);
11423 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11424 color = getPixelColor(device, 480, 360);
11425 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11426 color = getPixelColor(device, 480, 120);
11427 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11428 color = getPixelColor(device, 160, 120);
11429 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11431 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11432 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11435 out:
11436 if(vb) IDirect3DVertexBuffer9_Release(vb);
11437 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11438 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11439 if(ib)IDirect3DIndexBuffer9_Release(ib);
11440 if(shader)IDirect3DVertexShader9_Release(shader);
11441 refcount = IDirect3DDevice9_Release(device);
11442 ok(!refcount, "Device has %u references left.\n", refcount);
11443 done:
11444 IDirect3D9_Release(d3d);
11445 DestroyWindow(window);
11448 static void np2_stretch_rect_test(void)
11450 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11451 IDirect3DTexture9 *dsttex = NULL;
11452 IDirect3DDevice9 *device;
11453 IDirect3D9 *d3d;
11454 D3DCOLOR color;
11455 ULONG refcount;
11456 HWND window;
11457 HRESULT hr;
11459 static const D3DRECT r1 = {0, 0, 50, 50 };
11460 static const D3DRECT r2 = {50, 0, 100, 50 };
11461 static const D3DRECT r3 = {50, 50, 100, 100};
11462 static const D3DRECT r4 = {0, 50, 50, 100};
11463 static const float quad[] =
11465 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11466 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11467 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11468 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11471 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11472 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11473 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11474 ok(!!d3d, "Failed to create a D3D object.\n");
11475 if (!(device = create_device(d3d, window, window, TRUE)))
11477 skip("Failed to create a D3D device, skipping tests.\n");
11478 goto done;
11481 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11482 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11484 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11485 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11486 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11487 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11489 if(!src || !dsttex) {
11490 skip("One or more test resources could not be created\n");
11491 goto cleanup;
11494 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11495 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11497 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11498 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11500 /* Clear the StretchRect destination for debugging */
11501 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11502 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11504 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11506 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11509 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11510 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11511 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11512 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11513 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11514 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11515 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11518 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11519 * the target -> texture GL blit path
11521 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11522 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11523 IDirect3DSurface9_Release(dst);
11525 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11526 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11528 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11529 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11530 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11531 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11532 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11533 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11534 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11535 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11537 hr = IDirect3DDevice9_BeginScene(device);
11538 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11540 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11541 hr = IDirect3DDevice9_EndScene(device);
11542 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11544 color = getPixelColor(device, 160, 360);
11545 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11546 color = getPixelColor(device, 480, 360);
11547 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11548 color = getPixelColor(device, 480, 120);
11549 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11550 color = getPixelColor(device, 160, 120);
11551 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11552 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11553 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11555 cleanup:
11556 if(src) IDirect3DSurface9_Release(src);
11557 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11558 if(dsttex) IDirect3DTexture9_Release(dsttex);
11559 refcount = IDirect3DDevice9_Release(device);
11560 ok(!refcount, "Device has %u references left.\n", refcount);
11561 done:
11562 IDirect3D9_Release(d3d);
11563 DestroyWindow(window);
11566 static void texop_test(void)
11568 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11569 IDirect3DTexture9 *texture = NULL;
11570 D3DLOCKED_RECT locked_rect;
11571 IDirect3DDevice9 *device;
11572 IDirect3D9 *d3d;
11573 D3DCOLOR color;
11574 ULONG refcount;
11575 D3DCAPS9 caps;
11576 HWND window;
11577 HRESULT hr;
11578 unsigned i;
11580 static const struct {
11581 float x, y, z;
11582 float s, t;
11583 D3DCOLOR diffuse;
11584 } quad[] = {
11585 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11586 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11587 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11588 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11591 static const D3DVERTEXELEMENT9 decl_elements[] = {
11592 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11593 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11594 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11595 D3DDECL_END()
11598 static const struct {
11599 D3DTEXTUREOP op;
11600 const char *name;
11601 DWORD caps_flag;
11602 D3DCOLOR result;
11603 } test_data[] = {
11604 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11605 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
11606 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
11607 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
11608 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11609 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11610 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
11611 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11612 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11613 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11614 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11615 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
11616 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
11617 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11618 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11619 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
11620 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
11621 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11622 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
11623 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
11624 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
11625 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
11626 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
11629 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11630 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11631 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11632 ok(!!d3d, "Failed to create a D3D object.\n");
11633 if (!(device = create_device(d3d, window, window, TRUE)))
11635 skip("Failed to create a D3D device, skipping tests.\n");
11636 goto done;
11639 memset(&caps, 0, sizeof(caps));
11640 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11641 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11643 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11644 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
11645 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
11646 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
11648 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11649 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11650 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11651 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11652 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
11653 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11654 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11655 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11656 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11658 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
11659 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11660 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11661 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11662 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11663 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11665 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
11666 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11668 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11669 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
11671 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
11673 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11676 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11678 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
11680 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
11682 skip("tex operation %s not supported\n", test_data[i].name);
11683 continue;
11686 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
11687 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
11689 hr = IDirect3DDevice9_BeginScene(device);
11690 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11693 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11695 hr = IDirect3DDevice9_EndScene(device);
11696 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11698 color = getPixelColor(device, 320, 240);
11699 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
11700 test_data[i].name, color, test_data[i].result);
11702 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11703 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11706 IDirect3DTexture9_Release(texture);
11707 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11708 refcount = IDirect3DDevice9_Release(device);
11709 ok(!refcount, "Device has %u references left.\n", refcount);
11710 done:
11711 IDirect3D9_Release(d3d);
11712 DestroyWindow(window);
11715 static void yuv_color_test(void)
11717 HRESULT hr;
11718 IDirect3DSurface9 *surface, *target;
11719 unsigned int i;
11720 D3DLOCKED_RECT lr;
11721 IDirect3D9 *d3d;
11722 D3DCOLOR color;
11723 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
11724 IDirect3DDevice9 *device;
11725 D3DSURFACE_DESC desc;
11726 ULONG refcount;
11727 HWND window;
11729 static const struct
11731 DWORD in;
11732 D3DFORMAT format;
11733 const char *fmt_string;
11734 D3DCOLOR left, right;
11736 test_data[] =
11738 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
11739 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
11740 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
11741 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
11742 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
11743 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
11744 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
11745 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
11746 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
11747 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
11748 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
11749 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
11750 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
11751 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
11752 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
11753 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
11754 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
11755 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
11757 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
11758 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
11759 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
11760 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
11761 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
11762 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
11763 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
11764 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
11765 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
11766 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
11767 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
11768 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
11769 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
11770 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
11771 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
11772 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
11773 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
11774 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
11777 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11778 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11779 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11780 ok(!!d3d, "Failed to create a D3D object.\n");
11781 if (!(device = create_device(d3d, window, window, TRUE)))
11783 skip("Failed to create a D3D device, skipping tests.\n");
11784 goto done;
11787 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11788 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
11789 hr = IDirect3DSurface9_GetDesc(target, &desc);
11790 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11792 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11794 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
11795 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
11796 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11797 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
11799 if (skip_once != test_data[i].format)
11801 skip("%s is not supported.\n", test_data[i].fmt_string);
11802 skip_once = test_data[i].format;
11804 continue;
11806 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11807 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
11809 if (skip_once != test_data[i].format)
11811 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
11812 skip_once = test_data[i].format;
11814 continue;
11817 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
11818 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
11819 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
11820 * second luminance value, resulting in an incorrect color in the right pixel. */
11821 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
11822 D3DPOOL_DEFAULT, &surface, NULL);
11823 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
11826 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11827 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
11828 ((DWORD *)lr.pBits)[0] = test_data[i].in;
11829 ((DWORD *)lr.pBits)[1] = 0x00800080;
11830 hr = IDirect3DSurface9_UnlockRect(surface);
11831 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
11833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11834 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11835 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11836 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
11838 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11839 * although we asked for point filtering. Be careful when reading the results and use the pixel
11840 * centers. In the future we may want to add tests for the filtered pixels as well.
11842 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11843 * vastly differently, so we need a max diff of 18. */
11844 color = getPixelColor(device, 1, 240);
11845 ok(color_match(color, test_data[i].left, 18),
11846 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
11847 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
11848 color = getPixelColor(device, 318, 240);
11849 ok(color_match(color, test_data[i].right, 18),
11850 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
11851 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
11852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11853 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11854 IDirect3DSurface9_Release(surface);
11857 IDirect3DSurface9_Release(target);
11858 refcount = IDirect3DDevice9_Release(device);
11859 ok(!refcount, "Device has %u references left.\n", refcount);
11860 done:
11861 IDirect3D9_Release(d3d);
11862 DestroyWindow(window);
11865 static void yuv_layout_test(void)
11867 HRESULT hr;
11868 IDirect3DSurface9 *surface, *target;
11869 unsigned int fmt, i, x, y;
11870 D3DFORMAT format;
11871 const char *fmt_string;
11872 D3DLOCKED_RECT lr;
11873 IDirect3D9 *d3d;
11874 D3DCOLOR color;
11875 DWORD ref_color;
11876 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
11877 UINT width = 20, height = 16;
11878 IDirect3DDevice9 *device;
11879 ULONG refcount;
11880 D3DCAPS9 caps;
11881 D3DSURFACE_DESC desc;
11882 HWND window;
11884 static const struct
11886 DWORD color1, color2;
11887 DWORD rgb1, rgb2;
11889 test_data[] =
11891 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
11892 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
11893 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
11894 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
11895 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
11896 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
11897 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
11898 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
11901 static const struct
11903 D3DFORMAT format;
11904 const char *str;
11906 formats[] =
11908 { D3DFMT_UYVY, "D3DFMT_UYVY", },
11909 { D3DFMT_YUY2, "D3DFMT_YUY2", },
11910 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
11911 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
11914 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11915 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11916 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11917 ok(!!d3d, "Failed to create a D3D object.\n");
11918 if (!(device = create_device(d3d, window, window, TRUE)))
11920 skip("Failed to create a D3D device, skipping tests.\n");
11921 goto done;
11924 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11925 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11926 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
11927 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
11929 skip("No NP2 texture support, skipping YUV texture layout test.\n");
11930 IDirect3DDevice9_Release(device);
11931 goto done;
11934 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11935 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
11936 hr = IDirect3DSurface9_GetDesc(target, &desc);
11937 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11939 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
11941 format = formats[fmt].format;
11942 fmt_string = formats[fmt].str;
11944 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
11945 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
11946 * of drawPrimitive. */
11947 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
11948 D3DRTYPE_SURFACE, format) != D3D_OK)
11950 skip("%s is not supported.\n", fmt_string);
11951 continue;
11953 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11954 D3DDEVTYPE_HAL, format, desc.Format)))
11956 skip("Driver cannot blit %s surfaces.\n", fmt_string);
11957 continue;
11960 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
11961 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
11963 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11965 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11966 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
11967 buf = lr.pBits;
11968 chroma_buf = buf + lr.Pitch * height;
11969 if (format == MAKEFOURCC('Y','V','1','2'))
11971 v_buf = chroma_buf;
11972 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
11974 /* Draw the top left quarter of the screen with color1, the rest with color2 */
11975 for (y = 0; y < height; y++)
11977 for (x = 0; x < width; x += 2)
11979 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
11980 BYTE Y = (color >> 16) & 0xff;
11981 BYTE U = (color >> 8) & 0xff;
11982 BYTE V = (color >> 0) & 0xff;
11983 if (format == D3DFMT_UYVY)
11985 buf[y * lr.Pitch + 2 * x + 0] = U;
11986 buf[y * lr.Pitch + 2 * x + 1] = Y;
11987 buf[y * lr.Pitch + 2 * x + 2] = V;
11988 buf[y * lr.Pitch + 2 * x + 3] = Y;
11990 else if (format == D3DFMT_YUY2)
11992 buf[y * lr.Pitch + 2 * x + 0] = Y;
11993 buf[y * lr.Pitch + 2 * x + 1] = U;
11994 buf[y * lr.Pitch + 2 * x + 2] = Y;
11995 buf[y * lr.Pitch + 2 * x + 3] = V;
11997 else if (format == MAKEFOURCC('Y','V','1','2'))
11999 buf[y * lr.Pitch + x + 0] = Y;
12000 buf[y * lr.Pitch + x + 1] = Y;
12001 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12002 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12004 else if (format == MAKEFOURCC('N','V','1','2'))
12006 buf[y * lr.Pitch + x + 0] = Y;
12007 buf[y * lr.Pitch + x + 1] = Y;
12008 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12009 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12013 hr = IDirect3DSurface9_UnlockRect(surface);
12014 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12017 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12018 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12019 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12021 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12022 * although we asked for point filtering. To prevent running into precision problems, read at points
12023 * with some margin within each quadrant.
12025 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12026 * vastly differently, so we need a max diff of 18. */
12027 for (y = 0; y < 4; y++)
12029 for (x = 0; x < 4; x++)
12031 UINT xcoord = (1 + 2 * x) * 640 / 8;
12032 UINT ycoord = (1 + 2 * y) * 480 / 8;
12033 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12034 color = getPixelColor(device, xcoord, ycoord);
12035 ok(color_match(color, ref_color, 18),
12036 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12037 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12040 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12042 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12044 IDirect3DSurface9_Release(surface);
12047 IDirect3DSurface9_Release(target);
12048 refcount = IDirect3DDevice9_Release(device);
12049 ok(!refcount, "Device has %u references left.\n", refcount);
12050 done:
12051 IDirect3D9_Release(d3d);
12052 DestroyWindow(window);
12055 static void texop_range_test(void)
12057 IDirect3DTexture9 *texture;
12058 D3DLOCKED_RECT locked_rect;
12059 IDirect3DDevice9 *device;
12060 IDirect3D9 *d3d;
12061 ULONG refcount;
12062 D3DCAPS9 caps;
12063 DWORD color;
12064 HWND window;
12065 HRESULT hr;
12067 static const struct
12069 float x, y, z;
12070 D3DCOLOR diffuse;
12072 quad[] =
12074 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12075 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12076 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12077 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12080 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12081 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12082 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12083 ok(!!d3d, "Failed to create a D3D object.\n");
12084 if (!(device = create_device(d3d, window, window, TRUE)))
12086 skip("Failed to create a D3D device, skipping tests.\n");
12087 goto done;
12090 /* We need ADD and SUBTRACT operations */
12091 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12092 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12093 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12095 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12096 IDirect3DDevice9_Release(device);
12097 goto done;
12099 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12101 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12102 IDirect3DDevice9_Release(device);
12103 goto done;
12106 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12107 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12109 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12110 /* Stage 1: result = diffuse(=1.0) + diffuse
12111 * stage 2: result = result - tfactor(= 0.5)
12113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12114 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12115 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12116 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12117 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12118 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12119 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12120 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12121 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12122 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12123 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12124 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12125 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12126 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12128 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12129 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12130 hr = IDirect3DDevice9_BeginScene(device);
12131 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12134 hr = IDirect3DDevice9_EndScene(device);
12135 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12137 color = getPixelColor(device, 320, 240);
12138 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12139 color);
12140 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12141 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12143 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12144 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12145 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12146 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12147 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12148 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12149 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12150 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12151 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12153 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12154 * stage 2: result = result + diffuse(1.0)
12156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12157 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12158 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12159 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12160 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12161 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12163 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12164 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12165 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12166 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12167 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12168 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12169 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12171 hr = IDirect3DDevice9_BeginScene(device);
12172 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12174 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12175 hr = IDirect3DDevice9_EndScene(device);
12176 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12178 color = getPixelColor(device, 320, 240);
12179 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12180 color);
12181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12182 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12184 IDirect3DTexture9_Release(texture);
12185 refcount = IDirect3DDevice9_Release(device);
12186 ok(!refcount, "Device has %u references left.\n", refcount);
12187 done:
12188 IDirect3D9_Release(d3d);
12189 DestroyWindow(window);
12192 static void alphareplicate_test(void)
12194 IDirect3DDevice9 *device;
12195 IDirect3D9 *d3d;
12196 ULONG refcount;
12197 DWORD color;
12198 HWND window;
12199 HRESULT hr;
12201 static const struct
12203 struct vec3 position;
12204 DWORD diffuse;
12206 quad[] =
12208 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12209 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12210 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12211 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12214 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12215 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12216 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12217 ok(!!d3d, "Failed to create a D3D object.\n");
12218 if (!(device = create_device(d3d, window, window, TRUE)))
12220 skip("Failed to create a D3D device, skipping tests.\n");
12221 goto done;
12224 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12225 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12227 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12228 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12230 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12231 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12232 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12233 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12235 hr = IDirect3DDevice9_BeginScene(device);
12236 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12239 hr = IDirect3DDevice9_EndScene(device);
12240 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12242 color = getPixelColor(device, 320, 240);
12243 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12244 color);
12245 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12246 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12248 refcount = IDirect3DDevice9_Release(device);
12249 ok(!refcount, "Device has %u references left.\n", refcount);
12250 done:
12251 IDirect3D9_Release(d3d);
12252 DestroyWindow(window);
12255 static void dp3_alpha_test(void)
12257 IDirect3DDevice9 *device;
12258 IDirect3D9 *d3d;
12259 ULONG refcount;
12260 D3DCAPS9 caps;
12261 DWORD color;
12262 HWND window;
12263 HRESULT hr;
12265 static const struct
12267 struct vec3 position;
12268 DWORD diffuse;
12270 quad[] =
12272 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12273 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12274 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12275 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12278 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12279 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12280 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12281 ok(!!d3d, "Failed to create a D3D object.\n");
12282 if (!(device = create_device(d3d, window, window, TRUE)))
12284 skip("Failed to create a D3D device, skipping tests.\n");
12285 goto done;
12288 memset(&caps, 0, sizeof(caps));
12289 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12290 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12291 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12293 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12294 IDirect3DDevice9_Release(device);
12295 goto done;
12298 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12299 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12301 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12302 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12304 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12305 * mov r0.a, diffuse.a
12306 * mov r0, r0.a
12308 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12309 * 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
12310 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12312 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12313 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12314 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12315 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12318 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12319 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12320 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12321 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12322 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12323 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12324 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12325 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12326 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12327 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12329 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12331 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12333 hr = IDirect3DDevice9_BeginScene(device);
12334 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12336 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12337 hr = IDirect3DDevice9_EndScene(device);
12338 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12340 color = getPixelColor(device, 320, 240);
12341 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12342 color);
12343 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12344 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12346 refcount = IDirect3DDevice9_Release(device);
12347 ok(!refcount, "Device has %u references left.\n", refcount);
12348 done:
12349 IDirect3D9_Release(d3d);
12350 DestroyWindow(window);
12353 static void zwriteenable_test(void)
12355 IDirect3DDevice9 *device;
12356 IDirect3D9 *d3d;
12357 D3DCOLOR color;
12358 ULONG refcount;
12359 HWND window;
12360 HRESULT hr;
12362 static const struct
12364 struct vec3 position;
12365 DWORD diffuse;
12367 quad1[] =
12369 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12370 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12371 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12372 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12374 quad2[] =
12376 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12377 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12378 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12379 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12382 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12383 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12384 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12385 ok(!!d3d, "Failed to create a D3D object.\n");
12386 if (!(device = create_device(d3d, window, window, TRUE)))
12388 skip("Failed to create a D3D device, skipping tests.\n");
12389 goto done;
12392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12395 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12396 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12398 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12400 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12404 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12406 hr = IDirect3DDevice9_BeginScene(device);
12407 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12408 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12409 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12410 * because the z test is disabled. The question is whether the z = 0.1
12411 * values are written into the Z buffer. After the draw, set
12412 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12413 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12414 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12415 * green color is written. It turns out that the screen is green, so
12416 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12417 * buffer. */
12418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12419 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12421 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12423 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12424 hr = IDirect3DDevice9_EndScene(device);
12425 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12427 color = getPixelColor(device, 320, 240);
12428 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12429 color);
12430 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12431 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12433 refcount = IDirect3DDevice9_Release(device);
12434 ok(!refcount, "Device has %u references left.\n", refcount);
12435 done:
12436 IDirect3D9_Release(d3d);
12437 DestroyWindow(window);
12440 static void alphatest_test(void)
12442 #define ALPHATEST_PASSED 0x0000ff00
12443 #define ALPHATEST_FAILED 0x00ff0000
12444 IDirect3DDevice9 *device;
12445 unsigned int i, j;
12446 IDirect3D9 *d3d;
12447 D3DCOLOR color;
12448 ULONG refcount;
12449 D3DCAPS9 caps;
12450 HWND window;
12451 HRESULT hr;
12453 static const struct
12455 D3DCMPFUNC func;
12456 D3DCOLOR color_less;
12457 D3DCOLOR color_equal;
12458 D3DCOLOR color_greater;
12460 testdata[] =
12462 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12463 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12464 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12465 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12466 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12467 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12468 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12469 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12471 static const struct
12473 struct vec3 position;
12474 DWORD diffuse;
12476 quad[] =
12478 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12479 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12480 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12481 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12484 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12485 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12486 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12487 ok(!!d3d, "Failed to create a D3D object.\n");
12488 if (!(device = create_device(d3d, window, window, TRUE)))
12490 skip("Failed to create a D3D device, skipping tests.\n");
12491 goto done;
12494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12495 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12498 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12500 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12501 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12502 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12504 for (j = 0; j < 2; ++j)
12506 if (j == 1)
12508 /* Try a pixel shader instead of fixed function. The wined3d code
12509 * may emulate the alpha test either for performance reasons
12510 * (floating point RTs) or to work around driver bugs (GeForce
12511 * 7x00 cards on MacOS). There may be a different codepath for ffp
12512 * and shader in this case, and the test should cover both. */
12513 IDirect3DPixelShader9 *ps;
12514 static const DWORD shader_code[] =
12516 0xffff0101, /* ps_1_1 */
12517 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12518 0x0000ffff /* end */
12520 memset(&caps, 0, sizeof(caps));
12521 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12522 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12523 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12524 break;
12527 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12528 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12529 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12530 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12531 IDirect3DPixelShader9_Release(ps);
12534 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12536 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12539 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12542 hr = IDirect3DDevice9_BeginScene(device);
12543 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12545 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12546 hr = IDirect3DDevice9_EndScene(device);
12547 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12548 color = getPixelColor(device, 320, 240);
12549 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12550 color, testdata[i].color_less, testdata[i].func);
12551 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12552 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12554 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12558 hr = IDirect3DDevice9_BeginScene(device);
12559 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12561 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12562 hr = IDirect3DDevice9_EndScene(device);
12563 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12564 color = getPixelColor(device, 320, 240);
12565 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12566 color, testdata[i].color_equal, testdata[i].func);
12567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12568 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12570 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12571 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12573 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12574 hr = IDirect3DDevice9_BeginScene(device);
12575 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12577 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12578 hr = IDirect3DDevice9_EndScene(device);
12579 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12580 color = getPixelColor(device, 320, 240);
12581 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12582 color, testdata[i].color_greater, testdata[i].func);
12583 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12584 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12588 refcount = IDirect3DDevice9_Release(device);
12589 ok(!refcount, "Device has %u references left.\n", refcount);
12590 done:
12591 IDirect3D9_Release(d3d);
12592 DestroyWindow(window);
12595 static void sincos_test(void)
12597 IDirect3DVertexShader9 *sin_shader, *cos_shader;
12598 IDirect3DDevice9 *device;
12599 struct vec3 data[1280];
12600 IDirect3D9 *d3d;
12601 unsigned int i;
12602 ULONG refcount;
12603 D3DCAPS9 caps;
12604 HWND window;
12605 HRESULT hr;
12607 static const DWORD sin_shader_code[] =
12609 0xfffe0200, /* vs_2_0 */
12610 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12611 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12612 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12613 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
12614 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12615 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
12616 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
12617 0x0000ffff /* end */
12619 static const DWORD cos_shader_code[] =
12621 0xfffe0200, /* vs_2_0 */
12622 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12623 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12624 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12625 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
12626 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12627 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
12628 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
12629 0x0000ffff /* end */
12631 static const float sincosc1[4] = {D3DSINCOSCONST1};
12632 static const float sincosc2[4] = {D3DSINCOSCONST2};
12634 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12635 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12636 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12637 ok(!!d3d, "Failed to create a D3D object.\n");
12638 if (!(device = create_device(d3d, window, window, TRUE)))
12640 skip("Failed to create a D3D device, skipping tests.\n");
12641 goto done;
12644 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12645 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12646 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12648 skip("No vs_2_0 support, skipping tests.\n");
12649 IDirect3DDevice9_Release(device);
12650 goto done;
12653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12654 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12656 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
12657 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12658 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
12659 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12660 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12661 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12662 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
12663 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12664 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
12665 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12667 /* Generate a point from -1 to 1 every 0.5 pixels */
12668 for(i = 0; i < 1280; i++) {
12669 data[i].x = (-640.0 + i) / 640.0;
12670 data[i].y = 0.0;
12671 data[i].z = 0.1;
12674 hr = IDirect3DDevice9_BeginScene(device);
12675 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12677 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
12678 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
12679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12680 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12682 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
12683 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
12684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12685 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 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12691 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
12692 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
12694 IDirect3DVertexShader9_Release(sin_shader);
12695 IDirect3DVertexShader9_Release(cos_shader);
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 loop_index_test(void)
12705 IDirect3DVertexShader9 *shader;
12706 IDirect3DDevice9 *device;
12707 IDirect3D9 *d3d;
12708 float values[4];
12709 ULONG refcount;
12710 D3DCAPS9 caps;
12711 DWORD color;
12712 HWND window;
12713 HRESULT hr;
12715 static const DWORD shader_code[] =
12717 0xfffe0200, /* vs_2_0 */
12718 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12719 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
12720 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
12721 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
12722 0x0000001d, /* endloop */
12723 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12724 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
12725 0x0000ffff /* END */
12727 static const float quad[] =
12729 -1.0f, -1.0f, 0.1f,
12730 -1.0f, 1.0f, 0.1f,
12731 1.0f, -1.0f, 0.1f,
12732 1.0f, 1.0f, 0.1f,
12734 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
12735 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
12736 static const int i0[4] = {2, 10, -3, 0};
12738 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12739 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12740 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12741 ok(!!d3d, "Failed to create a D3D object.\n");
12742 if (!(device = create_device(d3d, window, window, TRUE)))
12744 skip("Failed to create a D3D device, skipping tests.\n");
12745 goto done;
12748 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12749 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12750 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12752 skip("No vs_2_0 support, skipping tests.\n");
12753 IDirect3DDevice9_Release(device);
12754 goto done;
12757 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12758 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12759 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12760 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12761 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12762 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12763 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12764 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12766 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
12767 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12768 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
12769 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12770 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
12771 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12772 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
12773 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12774 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
12775 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12776 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
12777 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12778 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
12779 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12780 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
12781 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12782 values[0] = 1.0;
12783 values[1] = 1.0;
12784 values[2] = 0.0;
12785 values[3] = 0.0;
12786 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
12787 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12788 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
12789 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12790 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
12791 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12792 values[0] = -1.0;
12793 values[1] = 0.0;
12794 values[2] = 0.0;
12795 values[3] = 0.0;
12796 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
12797 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12798 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
12799 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12800 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
12801 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12802 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
12803 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12804 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
12805 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12807 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
12808 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
12810 hr = IDirect3DDevice9_BeginScene(device);
12811 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12813 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12814 hr = IDirect3DDevice9_EndScene(device);
12815 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12816 color = getPixelColor(device, 320, 240);
12817 ok(color_match(color, 0x0000ff00, 1),
12818 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
12819 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12820 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12822 IDirect3DVertexShader9_Release(shader);
12823 refcount = IDirect3DDevice9_Release(device);
12824 ok(!refcount, "Device has %u references left.\n", refcount);
12825 done:
12826 IDirect3D9_Release(d3d);
12827 DestroyWindow(window);
12830 static void sgn_test(void)
12832 IDirect3DVertexShader9 *shader;
12833 IDirect3DDevice9 *device;
12834 IDirect3D9 *d3d;
12835 ULONG refcount;
12836 D3DCAPS9 caps;
12837 DWORD color;
12838 HWND window;
12839 HRESULT hr;
12841 static const DWORD shader_code[] =
12843 0xfffe0200, /* vs_2_0 */
12844 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
12845 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
12846 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
12847 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12848 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
12849 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
12850 0x0000ffff /* end */
12852 static const float quad[] =
12854 -1.0f, -1.0f, 0.1f,
12855 -1.0f, 1.0f, 0.1f,
12856 1.0f, -1.0f, 0.1f,
12857 1.0f, 1.0f, 0.1f,
12860 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12861 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12862 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12863 ok(!!d3d, "Failed to create a D3D object.\n");
12864 if (!(device = create_device(d3d, window, window, TRUE)))
12866 skip("Failed to create a D3D device, skipping tests.\n");
12867 goto done;
12870 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12871 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12872 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12874 skip("No vs_2_0 support, skipping tests.\n");
12875 IDirect3DDevice9_Release(device);
12876 goto done;
12879 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12880 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12881 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12882 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12884 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12886 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12888 hr = IDirect3DDevice9_BeginScene(device);
12889 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12891 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12892 hr = IDirect3DDevice9_EndScene(device);
12893 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12894 color = getPixelColor(device, 320, 240);
12895 ok(color_match(color, 0x008000ff, 1),
12896 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
12897 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12898 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12900 IDirect3DVertexShader9_Release(shader);
12901 refcount = IDirect3DDevice9_Release(device);
12902 ok(!refcount, "Device has %u references left.\n", refcount);
12903 done:
12904 IDirect3D9_Release(d3d);
12905 DestroyWindow(window);
12908 static void viewport_test(void)
12910 IDirect3DDevice9 *device;
12911 BOOL draw_failed = TRUE;
12912 D3DVIEWPORT9 vp;
12913 IDirect3D9 *d3d;
12914 ULONG refcount;
12915 DWORD color;
12916 HWND window;
12917 HRESULT hr;
12919 static const float quad[] =
12921 -0.5f, -0.5f, 0.1f,
12922 -0.5f, 0.5f, 0.1f,
12923 0.5f, -0.5f, 0.1f,
12924 0.5f, 0.5f, 0.1f,
12927 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12928 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12929 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12930 ok(!!d3d, "Failed to create a D3D object.\n");
12931 if (!(device = create_device(d3d, window, window, TRUE)))
12933 skip("Failed to create a D3D device, skipping tests.\n");
12934 goto done;
12937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12938 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12940 /* Test a viewport with Width and Height bigger than the surface dimensions
12942 * TODO: Test Width < surface.width, but X + Width > surface.width
12943 * TODO: Test Width < surface.width, what happens with the height?
12945 * The expected behavior is that the viewport behaves like the "default"
12946 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
12947 * MinZ = 0.0, MaxZ = 1.0.
12949 * Starting with Windows 7 the behavior among driver versions is not
12950 * consistent. The SetViewport call is accepted on all drivers. Some
12951 * drivers(older nvidia ones) refuse to draw and return an error. Newer
12952 * nvidia drivers draw, but use the actual values in the viewport and only
12953 * display the upper left part on the surface.
12955 memset(&vp, 0, sizeof(vp));
12956 vp.X = 0;
12957 vp.Y = 0;
12958 vp.Width = 10000;
12959 vp.Height = 10000;
12960 vp.MinZ = 0.0;
12961 vp.MaxZ = 0.0;
12962 hr = IDirect3DDevice9_SetViewport(device, &vp);
12963 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
12965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12966 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12968 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12969 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
12970 hr = IDirect3DDevice9_BeginScene(device);
12971 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12973 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
12974 draw_failed = FAILED(hr);
12975 hr = IDirect3DDevice9_EndScene(device);
12976 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12978 if(!draw_failed)
12980 color = getPixelColor(device, 158, 118);
12981 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
12982 color = getPixelColor(device, 162, 118);
12983 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
12984 color = getPixelColor(device, 158, 122);
12985 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
12986 color = getPixelColor(device, 162, 122);
12987 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
12989 color = getPixelColor(device, 478, 358);
12990 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
12991 color = getPixelColor(device, 482, 358);
12992 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
12993 color = getPixelColor(device, 478, 362);
12994 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
12995 color = getPixelColor(device, 482, 362);
12996 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
12999 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13000 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13002 refcount = IDirect3DDevice9_Release(device);
13003 ok(!refcount, "Device has %u references left.\n", refcount);
13004 done:
13005 IDirect3D9_Release(d3d);
13006 DestroyWindow(window);
13009 /* This test tests depth clamping / clipping behaviour:
13010 * - With software vertex processing, depth values are clamped to the
13011 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13012 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13013 * same as regular vertices here.
13014 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13015 * Normal vertices are always clipped. Pretransformed vertices are
13016 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13017 * - The viewport's MinZ/MaxZ is irrelevant for this.
13019 static void depth_clamp_test(void)
13021 IDirect3DDevice9 *device;
13022 D3DVIEWPORT9 vp;
13023 IDirect3D9 *d3d;
13024 D3DCOLOR color;
13025 ULONG refcount;
13026 D3DCAPS9 caps;
13027 HWND window;
13028 HRESULT hr;
13030 static const struct
13032 struct vec4 position;
13033 DWORD diffuse;
13035 quad1[] =
13037 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13038 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13039 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13040 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13042 quad2[] =
13044 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13045 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13046 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13047 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13049 quad3[] =
13051 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13052 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13053 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13054 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13056 quad4[] =
13058 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13059 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13060 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13061 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13063 static const struct
13065 struct vec3 position;
13066 DWORD diffuse;
13068 quad5[] =
13070 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13071 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13072 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13073 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13075 quad6[] =
13077 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13078 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13079 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13080 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13083 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13084 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13085 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13086 ok(!!d3d, "Failed to create a D3D object.\n");
13087 if (!(device = create_device(d3d, window, window, TRUE)))
13089 skip("Failed to create a D3D device, skipping tests.\n");
13090 goto done;
13093 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13094 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13096 vp.X = 0;
13097 vp.Y = 0;
13098 vp.Width = 640;
13099 vp.Height = 480;
13100 vp.MinZ = 0.0;
13101 vp.MaxZ = 7.5;
13103 hr = IDirect3DDevice9_SetViewport(device, &vp);
13104 if(FAILED(hr))
13106 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13107 * the tests because the 7.5 is just intended to show that it doesn't have
13108 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13109 * viewport and continue.
13111 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13112 vp.MaxZ = 1.0;
13113 hr = IDirect3DDevice9_SetViewport(device, &vp);
13115 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13118 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13121 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13123 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13125 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13127 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13129 hr = IDirect3DDevice9_BeginScene(device);
13130 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13132 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13133 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13136 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13138 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13141 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13143 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13144 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13146 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13149 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13151 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13152 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13155 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13158 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13161 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13163 hr = IDirect3DDevice9_EndScene(device);
13164 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13166 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13168 color = getPixelColor(device, 75, 75);
13169 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13170 color = getPixelColor(device, 150, 150);
13171 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13172 color = getPixelColor(device, 320, 240);
13173 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13174 color = getPixelColor(device, 320, 330);
13175 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13176 color = getPixelColor(device, 320, 330);
13177 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13179 else
13181 color = getPixelColor(device, 75, 75);
13182 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13183 color = getPixelColor(device, 150, 150);
13184 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13185 color = getPixelColor(device, 320, 240);
13186 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13187 color = getPixelColor(device, 320, 330);
13188 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13189 color = getPixelColor(device, 320, 330);
13190 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13193 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13194 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13196 refcount = IDirect3DDevice9_Release(device);
13197 ok(!refcount, "Device has %u references left.\n", refcount);
13198 done:
13199 IDirect3D9_Release(d3d);
13200 DestroyWindow(window);
13203 static void depth_bounds_test(void)
13205 static const struct
13207 struct vec4 position;
13208 DWORD diffuse;
13210 quad1[] =
13212 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13213 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13214 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13215 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13217 quad2[] =
13219 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13220 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13221 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13222 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13224 quad3[] =
13226 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13227 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13228 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13229 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13232 union {
13233 DWORD d;
13234 float f;
13235 } tmpvalue;
13237 IDirect3DSurface9 *offscreen_surface = NULL;
13238 IDirect3DDevice9 *device;
13239 IDirect3D9 *d3d;
13240 D3DCOLOR color;
13241 ULONG refcount;
13242 HWND window;
13243 HRESULT hr;
13245 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13246 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13247 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13248 ok(!!d3d, "Failed to create a D3D object.\n");
13249 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13250 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13252 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13253 goto done;
13255 if (!(device = create_device(d3d, window, window, TRUE)))
13257 skip("Failed to create a D3D device, skipping tests.\n");
13258 goto done;
13261 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13262 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13263 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13264 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13267 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13270 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13272 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13274 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13276 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13279 hr = IDirect3DDevice9_BeginScene(device);
13280 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13282 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13283 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13286 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13289 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13291 tmpvalue.f = 0.625;
13292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13293 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13295 tmpvalue.f = 0.75;
13296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13297 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13302 tmpvalue.f = 0.75;
13303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13304 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13307 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13310 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13312 hr = IDirect3DDevice9_EndScene(device);
13313 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13315 color = getPixelColor(device, 150, 130);
13316 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13317 color = getPixelColor(device, 150, 200);
13318 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13319 color = getPixelColor(device, 150, 300-5);
13320 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13321 color = getPixelColor(device, 150, 300+5);
13322 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13323 color = getPixelColor(device, 150, 330);
13324 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13325 color = getPixelColor(device, 150, 360-5);
13326 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13327 color = getPixelColor(device, 150, 360+5);
13328 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13330 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13331 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13332 refcount = IDirect3DDevice9_Release(device);
13333 ok(!refcount, "Device has %u references left.\n", refcount);
13334 done:
13335 IDirect3D9_Release(d3d);
13336 DestroyWindow(window);
13339 static void depth_buffer_test(void)
13341 static const struct
13343 struct vec3 position;
13344 DWORD diffuse;
13346 quad1[] =
13348 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13349 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13350 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13351 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13353 quad2[] =
13355 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13356 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13357 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13358 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13360 quad3[] =
13362 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13363 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13364 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13365 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13367 static const DWORD expected_colors[4][4] =
13369 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13370 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13371 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13372 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13375 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13376 IDirect3DDevice9 *device;
13377 unsigned int i, j;
13378 D3DVIEWPORT9 vp;
13379 IDirect3D9 *d3d;
13380 D3DCOLOR color;
13381 ULONG refcount;
13382 HWND window;
13383 HRESULT hr;
13385 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13386 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13387 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13388 ok(!!d3d, "Failed to create a D3D object.\n");
13389 if (!(device = create_device(d3d, window, window, TRUE)))
13391 skip("Failed to create a D3D device, skipping tests.\n");
13392 goto done;
13395 vp.X = 0;
13396 vp.Y = 0;
13397 vp.Width = 640;
13398 vp.Height = 480;
13399 vp.MinZ = 0.0;
13400 vp.MaxZ = 1.0;
13402 hr = IDirect3DDevice9_SetViewport(device, &vp);
13403 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13406 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13408 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13410 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13412 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13413 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13414 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13416 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13417 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13418 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13419 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13420 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13421 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13422 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13423 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13424 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13425 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13426 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13428 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13429 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13431 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13433 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13434 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13436 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13438 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13439 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13440 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13441 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13443 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13444 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13445 hr = IDirect3DDevice9_BeginScene(device);
13446 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13447 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13448 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13449 hr = IDirect3DDevice9_EndScene(device);
13450 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13452 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13453 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13456 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13458 hr = IDirect3DDevice9_BeginScene(device);
13459 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13461 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13463 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13464 hr = IDirect3DDevice9_EndScene(device);
13465 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13467 for (i = 0; i < 4; ++i)
13469 for (j = 0; j < 4; ++j)
13471 unsigned int x = 80 * ((2 * j) + 1);
13472 unsigned int y = 60 * ((2 * i) + 1);
13473 color = getPixelColor(device, x, y);
13474 ok(color_match(color, expected_colors[i][j], 0),
13475 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13479 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13480 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13482 IDirect3DSurface9_Release(backbuffer);
13483 IDirect3DSurface9_Release(rt3);
13484 IDirect3DSurface9_Release(rt2);
13485 IDirect3DSurface9_Release(rt1);
13486 refcount = IDirect3DDevice9_Release(device);
13487 ok(!refcount, "Device has %u references left.\n", refcount);
13488 done:
13489 IDirect3D9_Release(d3d);
13490 DestroyWindow(window);
13493 /* Test that partial depth copies work the way they're supposed to. The clear
13494 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13495 * the following draw should only copy back the part that was modified. */
13496 static void depth_buffer2_test(void)
13498 static const struct
13500 struct vec3 position;
13501 DWORD diffuse;
13503 quad[] =
13505 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13506 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13507 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13508 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13511 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13512 IDirect3DDevice9 *device;
13513 unsigned int i, j;
13514 D3DVIEWPORT9 vp;
13515 IDirect3D9 *d3d;
13516 D3DCOLOR color;
13517 ULONG refcount;
13518 HWND window;
13519 HRESULT hr;
13521 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13522 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13523 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13524 ok(!!d3d, "Failed to create a D3D object.\n");
13525 if (!(device = create_device(d3d, window, window, TRUE)))
13527 skip("Failed to create a D3D device, skipping tests.\n");
13528 goto done;
13531 vp.X = 0;
13532 vp.Y = 0;
13533 vp.Width = 640;
13534 vp.Height = 480;
13535 vp.MinZ = 0.0;
13536 vp.MaxZ = 1.0;
13538 hr = IDirect3DDevice9_SetViewport(device, &vp);
13539 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13542 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13544 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13546 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13548 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13549 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13550 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13552 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13553 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13554 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13555 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13556 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13557 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13558 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13559 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13561 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13562 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13563 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13564 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13566 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13567 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13569 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13571 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13572 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13574 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13576 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13577 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13580 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13582 hr = IDirect3DDevice9_BeginScene(device);
13583 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13585 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13586 hr = IDirect3DDevice9_EndScene(device);
13587 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13589 for (i = 0; i < 4; ++i)
13591 for (j = 0; j < 4; ++j)
13593 unsigned int x = 80 * ((2 * j) + 1);
13594 unsigned int y = 60 * ((2 * i) + 1);
13595 color = getPixelColor(device, x, y);
13596 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
13597 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
13601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13602 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13604 IDirect3DSurface9_Release(backbuffer);
13605 IDirect3DSurface9_Release(rt2);
13606 IDirect3DSurface9_Release(rt1);
13607 refcount = IDirect3DDevice9_Release(device);
13608 ok(!refcount, "Device has %u references left.\n", refcount);
13609 done:
13610 IDirect3D9_Release(d3d);
13611 DestroyWindow(window);
13614 static void depth_blit_test(void)
13616 static const struct
13618 struct vec3 position;
13619 DWORD diffuse;
13621 quad1[] =
13623 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
13624 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
13625 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
13626 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
13628 quad2[] =
13630 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
13631 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
13632 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
13633 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
13635 static const DWORD expected_colors[4][4] =
13637 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13638 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13639 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13640 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13643 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
13644 IDirect3DDevice9 *device;
13645 RECT src_rect, dst_rect;
13646 unsigned int i, j;
13647 D3DVIEWPORT9 vp;
13648 IDirect3D9 *d3d;
13649 D3DCOLOR color;
13650 ULONG refcount;
13651 HWND window;
13652 HRESULT hr;
13654 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13655 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13656 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13657 ok(!!d3d, "Failed to create a D3D object.\n");
13658 if (!(device = create_device(d3d, window, window, TRUE)))
13660 skip("Failed to create a D3D device, skipping tests.\n");
13661 goto done;
13664 vp.X = 0;
13665 vp.Y = 0;
13666 vp.Width = 640;
13667 vp.Height = 480;
13668 vp.MinZ = 0.0;
13669 vp.MaxZ = 1.0;
13671 hr = IDirect3DDevice9_SetViewport(device, &vp);
13672 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13674 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13675 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13676 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
13677 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13678 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
13679 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13680 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
13681 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13682 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
13683 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13685 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13686 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13688 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13690 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13691 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13692 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13695 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13696 SetRect(&dst_rect, 0, 0, 480, 360);
13697 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
13698 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13699 SetRect(&dst_rect, 0, 0, 320, 240);
13700 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13701 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13703 /* Partial blit. */
13704 SetRect(&src_rect, 0, 0, 320, 240);
13705 SetRect(&dst_rect, 0, 0, 320, 240);
13706 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13707 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13708 /* Flipped. */
13709 SetRect(&src_rect, 0, 0, 640, 480);
13710 SetRect(&dst_rect, 0, 480, 640, 0);
13711 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13712 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13713 /* Full, explicit. */
13714 SetRect(&src_rect, 0, 0, 640, 480);
13715 SetRect(&dst_rect, 0, 0, 640, 480);
13716 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13717 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13718 /* Filtered blit. */
13719 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
13720 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13721 /* Depth -> color blit.*/
13722 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
13723 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13724 IDirect3DSurface9_Release(backbuffer);
13725 /* Full surface, different sizes */
13726 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
13727 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13728 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
13729 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13731 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
13732 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13733 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
13734 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13735 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
13736 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13739 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13740 hr = IDirect3DDevice9_BeginScene(device);
13741 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13742 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13743 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13745 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13746 hr = IDirect3DDevice9_EndScene(device);
13747 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13749 for (i = 0; i < 4; ++i)
13751 for (j = 0; j < 4; ++j)
13753 unsigned int x = 80 * ((2 * j) + 1);
13754 unsigned int y = 60 * ((2 * i) + 1);
13755 color = getPixelColor(device, x, y);
13756 ok(color_match(color, expected_colors[i][j], 0),
13757 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13761 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13762 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13764 IDirect3DSurface9_Release(ds3);
13765 IDirect3DSurface9_Release(ds2);
13766 IDirect3DSurface9_Release(ds1);
13767 refcount = IDirect3DDevice9_Release(device);
13768 ok(!refcount, "Device has %u references left.\n", refcount);
13769 done:
13770 IDirect3D9_Release(d3d);
13771 DestroyWindow(window);
13774 static void intz_test(void)
13776 static const DWORD ps_code[] =
13778 0xffff0200, /* ps_2_0 */
13779 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13780 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13781 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13782 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13783 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13784 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13785 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13786 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13787 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13788 0x0000ffff, /* end */
13790 struct
13792 float x, y, z;
13793 float s, t, p, q;
13795 quad[] =
13797 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13798 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13799 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13800 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13802 half_quad_1[] =
13804 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13805 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13806 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13807 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13809 half_quad_2[] =
13811 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13812 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13813 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13814 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13816 struct
13818 UINT x, y;
13819 D3DCOLOR color;
13821 expected_colors[] =
13823 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13824 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13825 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13826 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13827 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13828 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13829 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13830 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13833 IDirect3DSurface9 *original_rt, *rt;
13834 IDirect3DTexture9 *texture;
13835 IDirect3DPixelShader9 *ps;
13836 IDirect3DDevice9 *device;
13837 IDirect3DSurface9 *ds;
13838 IDirect3D9 *d3d;
13839 ULONG refcount;
13840 D3DCAPS9 caps;
13841 HWND window;
13842 HRESULT hr;
13843 UINT i;
13845 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13846 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13847 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13848 ok(!!d3d, "Failed to create a D3D object.\n");
13849 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13850 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
13852 skip("No INTZ support, skipping INTZ test.\n");
13853 goto done;
13855 if (!(device = create_device(d3d, window, window, TRUE)))
13857 skip("Failed to create a D3D device, skipping tests.\n");
13858 goto done;
13861 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13862 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13863 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13865 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13866 IDirect3DDevice9_Release(device);
13867 goto done;
13869 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13871 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13872 IDirect3DDevice9_Release(device);
13873 goto done;
13876 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13877 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13879 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13880 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13881 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13882 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13883 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13884 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13885 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13886 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13888 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13889 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13891 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13893 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13895 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13896 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13897 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13899 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13900 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13901 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13902 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13903 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13904 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13905 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13906 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13907 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13908 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13910 /* Render offscreen, using the INTZ texture as depth buffer */
13911 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13912 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13913 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13914 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13915 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13916 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13917 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13918 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13920 /* Setup the depth/stencil surface. */
13921 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13922 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13924 hr = IDirect3DDevice9_BeginScene(device);
13925 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13927 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13928 hr = IDirect3DDevice9_EndScene(device);
13929 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13931 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13932 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13933 IDirect3DSurface9_Release(ds);
13934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13935 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13936 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13937 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13938 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13939 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13941 /* Read the depth values back. */
13942 hr = IDirect3DDevice9_BeginScene(device);
13943 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13946 hr = IDirect3DDevice9_EndScene(device);
13947 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13949 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13951 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13952 ok(color_match(color, expected_colors[i].color, 1),
13953 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13954 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13957 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13958 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13960 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13961 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13962 IDirect3DTexture9_Release(texture);
13964 /* Render onscreen while using the INTZ texture as depth buffer */
13965 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13966 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13967 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13968 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13969 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13970 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13971 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13972 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13974 /* Setup the depth/stencil surface. */
13975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13976 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13978 hr = IDirect3DDevice9_BeginScene(device);
13979 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13980 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13981 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13982 hr = IDirect3DDevice9_EndScene(device);
13983 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13985 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13986 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13987 IDirect3DSurface9_Release(ds);
13988 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13989 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13990 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13991 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13993 /* Read the depth values back. */
13994 hr = IDirect3DDevice9_BeginScene(device);
13995 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13997 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13998 hr = IDirect3DDevice9_EndScene(device);
13999 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14001 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14003 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14004 ok(color_match(color, expected_colors[i].color, 1),
14005 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14006 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14009 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14010 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14012 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14013 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14014 IDirect3DTexture9_Release(texture);
14016 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14017 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14018 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14019 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14020 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14022 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14023 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14024 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14025 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14026 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14027 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14029 /* Setup the depth/stencil surface. */
14030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14031 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14033 hr = IDirect3DDevice9_BeginScene(device);
14034 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14036 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14037 hr = IDirect3DDevice9_EndScene(device);
14038 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14040 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14041 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14043 hr = IDirect3DDevice9_BeginScene(device);
14044 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14045 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14046 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14047 hr = IDirect3DDevice9_EndScene(device);
14048 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14050 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14051 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14052 IDirect3DSurface9_Release(ds);
14053 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14054 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14055 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14056 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14058 /* Read the depth values back. */
14059 hr = IDirect3DDevice9_BeginScene(device);
14060 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14063 hr = IDirect3DDevice9_EndScene(device);
14064 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14066 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14068 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14069 ok(color_match(color, expected_colors[i].color, 1),
14070 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14071 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14075 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14077 IDirect3DTexture9_Release(texture);
14078 IDirect3DPixelShader9_Release(ps);
14079 IDirect3DSurface9_Release(original_rt);
14080 IDirect3DSurface9_Release(rt);
14081 refcount = IDirect3DDevice9_Release(device);
14082 ok(!refcount, "Device has %u references left.\n", refcount);
14083 done:
14084 IDirect3D9_Release(d3d);
14085 DestroyWindow(window);
14088 static void shadow_test(void)
14090 static const DWORD ps_code[] =
14092 0xffff0200, /* ps_2_0 */
14093 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14094 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14095 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14096 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14097 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14098 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
14099 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
14100 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
14101 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
14102 0x0000ffff, /* end */
14104 struct
14106 D3DFORMAT format;
14107 const char *name;
14109 formats[] =
14111 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14112 {D3DFMT_D32, "D3DFMT_D32"},
14113 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14114 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14115 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14116 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14117 {D3DFMT_D16, "D3DFMT_D16"},
14118 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14119 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14121 struct
14123 float x, y, z;
14124 float s, t, p, q;
14126 quad[] =
14128 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14129 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14130 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14131 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14133 struct
14135 UINT x, y;
14136 D3DCOLOR color;
14138 expected_colors[] =
14140 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14141 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14142 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14143 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14144 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14145 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14146 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14147 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14150 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14151 IDirect3DPixelShader9 *ps;
14152 IDirect3DDevice9 *device;
14153 IDirect3D9 *d3d;
14154 ULONG refcount;
14155 D3DCAPS9 caps;
14156 HWND window;
14157 HRESULT hr;
14158 UINT i;
14160 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14161 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14162 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14163 ok(!!d3d, "Failed to create a D3D object.\n");
14164 if (!(device = create_device(d3d, window, window, TRUE)))
14166 skip("Failed to create a D3D device, skipping tests.\n");
14167 goto done;
14170 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14171 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14172 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14174 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14175 IDirect3DDevice9_Release(device);
14176 goto done;
14179 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14180 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14181 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14182 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14184 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14185 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14186 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14187 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14188 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14190 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14191 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14192 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14193 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14195 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14197 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14199 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14201 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14202 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14203 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14204 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14205 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14206 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14207 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14208 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14209 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14210 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14212 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14214 D3DFORMAT format = formats[i].format;
14215 IDirect3DTexture9 *texture;
14216 IDirect3DSurface9 *ds;
14217 unsigned int j;
14219 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14220 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14221 continue;
14223 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14224 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14225 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14227 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14228 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14230 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14231 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14233 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14234 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14236 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14237 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14239 /* Setup the depth/stencil surface. */
14240 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14241 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14243 hr = IDirect3DDevice9_BeginScene(device);
14244 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14246 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14247 hr = IDirect3DDevice9_EndScene(device);
14248 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14250 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14251 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14252 IDirect3DSurface9_Release(ds);
14254 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14255 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14257 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14258 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14260 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14261 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14263 /* Do the actual shadow mapping. */
14264 hr = IDirect3DDevice9_BeginScene(device);
14265 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14267 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14268 hr = IDirect3DDevice9_EndScene(device);
14269 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14271 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14272 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14273 IDirect3DTexture9_Release(texture);
14275 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14277 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
14278 ok(color_match(color, expected_colors[j].color, 0),
14279 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14280 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14281 formats[i].name, color);
14284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14285 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14288 IDirect3DPixelShader9_Release(ps);
14289 IDirect3DSurface9_Release(original_ds);
14290 IDirect3DSurface9_Release(original_rt);
14291 IDirect3DSurface9_Release(rt);
14292 refcount = IDirect3DDevice9_Release(device);
14293 ok(!refcount, "Device has %u references left.\n", refcount);
14294 done:
14295 IDirect3D9_Release(d3d);
14296 DestroyWindow(window);
14299 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14301 static const struct
14303 struct vec3 position;
14304 DWORD diffuse;
14306 quad1[] =
14308 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14309 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14310 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14311 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14313 quad2[] =
14315 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14316 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14317 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14318 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14320 D3DCOLOR color;
14321 HRESULT hr;
14323 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14324 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14326 hr = IDirect3DDevice9_BeginScene(device);
14327 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14329 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14330 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14333 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14335 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14337 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14338 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14339 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14340 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14342 hr = IDirect3DDevice9_EndScene(device);
14343 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14345 color = getPixelColor(device, 1, 240);
14346 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14347 color = getPixelColor(device, 638, 240);
14348 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14350 color = getPixelColor(device, 1, 241);
14351 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14352 color = getPixelColor(device, 638, 241);
14353 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14356 static void clip_planes_test(void)
14358 IDirect3DSurface9 *offscreen_surface, *original_rt;
14359 IDirect3DTexture9 *offscreen = NULL;
14360 IDirect3DVertexShader9 *shader;
14361 IDirect3DDevice9 *device;
14362 IDirect3D9 *d3d;
14363 ULONG refcount;
14364 D3DCAPS9 caps;
14365 HWND window;
14366 HRESULT hr;
14368 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14369 static const DWORD shader_code[] =
14371 0xfffe0200, /* vs_2_0 */
14372 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14373 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14374 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14375 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14376 0x0000ffff /* end */
14379 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14380 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14381 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14382 ok(!!d3d, "Failed to create a D3D object.\n");
14383 if (!(device = create_device(d3d, window, window, TRUE)))
14385 skip("Failed to create a D3D device, skipping tests.\n");
14386 goto done;
14389 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14390 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14391 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14393 skip("No vs_2_0 support, skipping tests.\n");
14394 IDirect3DDevice9_Release(device);
14395 goto done;
14398 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14399 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14402 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14404 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14406 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14408 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14410 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14411 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14412 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14413 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14415 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14417 clip_planes(device, "Onscreen FFP");
14419 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14420 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14421 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14422 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14423 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14424 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14426 clip_planes(device, "Offscreen FFP");
14428 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14429 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14431 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14432 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14433 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14434 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14436 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14439 clip_planes(device, "Onscreen vertex shader");
14441 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14444 clip_planes(device, "Offscreen vertex shader");
14446 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14447 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14449 IDirect3DVertexShader9_Release(shader);
14450 IDirect3DSurface9_Release(original_rt);
14451 IDirect3DSurface9_Release(offscreen_surface);
14452 IDirect3DTexture9_Release(offscreen);
14453 refcount = IDirect3DDevice9_Release(device);
14454 ok(!refcount, "Device has %u references left.\n", refcount);
14455 done:
14456 IDirect3D9_Release(d3d);
14457 DestroyWindow(window);
14460 static void fp_special_test(void)
14462 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14463 static const DWORD vs_header[] =
14465 0xfffe0200, /* vs_2_0 */
14466 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14467 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14468 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14469 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14472 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14473 static const DWORD vs_pow[] =
14474 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14475 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14476 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14477 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14478 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14479 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14480 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14481 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14482 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14483 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14484 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14486 static const DWORD vs_footer[] =
14488 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14489 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14490 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14491 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14492 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14493 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14494 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14495 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14496 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14497 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14498 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14499 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14500 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14501 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14502 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14503 0x0000ffff, /* end */
14506 static const struct
14508 const char *name;
14509 const DWORD *ops;
14510 DWORD size;
14511 D3DCOLOR r500;
14512 D3DCOLOR r600;
14513 D3DCOLOR nv40;
14514 D3DCOLOR nv50;
14515 D3DCOLOR warp;
14517 vs_body[] =
14519 /* The basic ideas here are:
14520 * 2.0 * +/-INF == +/-INF
14521 * NAN != NAN
14523 * The vertex shader value is written to the red component, with 0.0
14524 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14525 * result in 0x00. The pixel shader value is written to the green
14526 * component, but here 0.0 also results in 0x00. The actual value is
14527 * written to the blue component.
14529 * There are considerable differences between graphics cards in how
14530 * these are handled, but pow and nrm never generate INF or NAN on
14531 * real hardware. */
14532 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14533 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14534 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14535 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14536 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14537 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14538 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14539 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14540 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14541 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14542 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14545 static const DWORD ps_code[] =
14547 0xffff0200, /* ps_2_0 */
14548 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14549 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14550 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14551 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14552 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14553 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14554 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14555 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14556 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14557 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14558 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14559 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14560 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14561 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14562 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14563 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14564 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14565 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14566 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14567 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14568 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14569 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14570 0x0000ffff, /* end */
14573 struct
14575 float x, y, z;
14576 float s;
14578 quad[] =
14580 { -1.0f, 1.0f, 0.0f, 0.0f},
14581 { 1.0f, 1.0f, 1.0f, 0.0f},
14582 { -1.0f, -1.0f, 0.0f, 0.0f},
14583 { 1.0f, -1.0f, 1.0f, 0.0f},
14586 IDirect3DPixelShader9 *ps;
14587 IDirect3DDevice9 *device;
14588 UINT body_size = 0;
14589 IDirect3D9 *d3d;
14590 DWORD *vs_code;
14591 ULONG refcount;
14592 D3DCAPS9 caps;
14593 HWND window;
14594 HRESULT hr;
14595 UINT i;
14597 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14598 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14599 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14600 ok(!!d3d, "Failed to create a D3D object.\n");
14601 if (!(device = create_device(d3d, window, window, TRUE)))
14603 skip("Failed to create a D3D device, skipping tests.\n");
14604 goto done;
14607 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14608 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14609 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14611 skip("No shader model 2.0 support, skipping floating point specials test.\n");
14612 IDirect3DDevice9_Release(device);
14613 goto done;
14616 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
14617 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14619 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14620 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14621 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14622 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14625 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14627 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
14628 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14630 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14632 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
14635 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
14636 memcpy(vs_code, vs_header, sizeof(vs_header));
14638 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14640 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
14641 IDirect3DVertexShader9 *vs;
14642 D3DCOLOR color;
14644 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
14645 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
14646 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
14648 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
14649 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
14650 hr = IDirect3DDevice9_SetVertexShader(device, vs);
14651 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14653 hr = IDirect3DDevice9_BeginScene(device);
14654 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14656 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14657 hr = IDirect3DDevice9_EndScene(device);
14658 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14660 color = getPixelColor(device, 320, 240);
14661 ok(color_match(color, vs_body[i].r500, 1)
14662 || color_match(color, vs_body[i].r600, 1)
14663 || color_match(color, vs_body[i].nv40, 1)
14664 || color_match(color, vs_body[i].nv50, 1)
14665 || broken(color_match(color, vs_body[i].warp, 1)),
14666 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
14667 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
14669 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14670 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14672 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14673 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14674 IDirect3DVertexShader9_Release(vs);
14677 HeapFree(GetProcessHeap(), 0, vs_code);
14679 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14680 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14681 IDirect3DPixelShader9_Release(ps);
14682 refcount = IDirect3DDevice9_Release(device);
14683 ok(!refcount, "Device has %u references left.\n", refcount);
14684 done:
14685 IDirect3D9_Release(d3d);
14686 DestroyWindow(window);
14689 static void srgbwrite_format_test(void)
14691 IDirect3D9 *d3d;
14692 IDirect3DSurface9 *rt, *backbuffer;
14693 IDirect3DTexture9 *texture;
14694 IDirect3DDevice9 *device;
14695 ULONG refcount;
14696 HWND window;
14697 HRESULT hr;
14698 int i;
14699 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
14700 static const struct
14702 D3DFORMAT fmt;
14703 const char *name;
14705 formats[] =
14707 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
14708 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
14709 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
14710 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
14711 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
14713 static const struct
14715 float x, y, z;
14716 float u, v;
14718 quad[] =
14720 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14721 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14722 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14723 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14726 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14727 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14728 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14729 ok(!!d3d, "Failed to create a D3D object.\n");
14730 if (!(device = create_device(d3d, window, window, TRUE)))
14732 skip("Failed to create a D3D device, skipping tests.\n");
14733 goto done;
14736 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
14737 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14738 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
14739 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
14740 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14741 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
14743 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14745 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
14747 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14748 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
14750 skip("Format %s not supported as render target, skipping test.\n",
14751 formats[i].name);
14752 continue;
14755 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
14756 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
14757 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14759 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14761 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
14762 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14763 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14764 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
14766 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14768 hr = IDirect3DDevice9_BeginScene(device);
14769 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
14772 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
14773 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
14774 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
14775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14776 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14778 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
14779 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
14780 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14781 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14782 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
14783 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
14784 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14785 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
14786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14787 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14788 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14789 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
14791 hr = IDirect3DDevice9_EndScene(device);
14792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14794 IDirect3DSurface9_Release(rt);
14795 IDirect3DTexture9_Release(texture);
14797 color = getPixelColor(device, 360, 240);
14798 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14799 D3DUSAGE_QUERY_SRGBWRITE,
14800 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
14802 /* Big slop for R5G6B5 */
14803 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
14804 formats[i].name, color_srgb, color);
14806 else
14808 /* Big slop for R5G6B5 */
14809 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
14810 formats[i].name, color_rgb, color);
14813 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14814 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14817 IDirect3DSurface9_Release(backbuffer);
14818 refcount = IDirect3DDevice9_Release(device);
14819 ok(!refcount, "Device has %u references left.\n", refcount);
14820 done:
14821 IDirect3D9_Release(d3d);
14822 DestroyWindow(window);
14825 static void ds_size_test(void)
14827 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
14828 IDirect3DDevice9 *device;
14829 DWORD num_passes;
14830 IDirect3D9 *d3d;
14831 ULONG refcount;
14832 HWND window;
14833 HRESULT hr;
14835 static const struct
14837 float x, y, z;
14839 quad[] =
14841 {-1.0f, -1.0f, 0.0f},
14842 {-1.0f, 1.0f, 0.0f},
14843 { 1.0f, -1.0f, 0.0f},
14844 { 1.0f, 1.0f, 0.0f},
14847 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14848 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14849 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14850 ok(!!d3d, "Failed to create a D3D object.\n");
14851 if (!(device = create_device(d3d, window, window, TRUE)))
14853 skip("Failed to create a D3D device, skipping tests.\n");
14854 goto done;
14857 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14858 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14859 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
14860 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
14861 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
14862 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
14864 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14865 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
14867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14868 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
14870 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14872 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14873 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14874 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14875 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14876 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14877 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
14878 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
14879 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14880 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14881 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14882 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14883 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14884 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14886 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
14887 * but does not change the surface's contents. */
14888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
14889 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
14890 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
14891 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
14892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
14893 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
14895 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
14897 /* Turning on any depth-related state results in a ValidateDevice failure */
14898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14899 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14900 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14901 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14902 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14903 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14904 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14906 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14907 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14908 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14909 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14911 /* Try to draw with the device in an invalid state. */
14912 hr = IDirect3DDevice9_BeginScene(device);
14913 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14915 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14916 hr = IDirect3DDevice9_EndScene(device);
14917 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14919 /* Don't check the resulting draw unless we find an app that needs it. On
14920 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
14921 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
14922 * 0.0 for all pixels, even those that are covered by the depth buffer. */
14924 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
14925 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14926 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
14927 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14928 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14929 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14931 IDirect3DSurface9_Release(readback);
14932 IDirect3DSurface9_Release(ds);
14933 IDirect3DSurface9_Release(rt);
14934 IDirect3DSurface9_Release(old_rt);
14935 IDirect3DSurface9_Release(old_ds);
14936 refcount = IDirect3DDevice9_Release(device);
14937 ok(!refcount, "Device has %u references left.\n", refcount);
14938 done:
14939 IDirect3D9_Release(d3d);
14940 DestroyWindow(window);
14943 static void unbound_sampler_test(void)
14945 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
14946 IDirect3DSurface9 *rt, *old_rt;
14947 IDirect3DDevice9 *device;
14948 IDirect3D9 *d3d;
14949 ULONG refcount;
14950 D3DCAPS9 caps;
14951 DWORD color;
14952 HWND window;
14953 HRESULT hr;
14955 static const DWORD ps_code[] =
14957 0xffff0200, /* ps_2_0 */
14958 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14959 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14960 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14961 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14962 0x0000ffff, /* end */
14964 static const DWORD ps_code_cube[] =
14966 0xffff0200, /* ps_2_0 */
14967 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
14968 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14969 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14970 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14971 0x0000ffff, /* end */
14973 static const DWORD ps_code_volume[] =
14975 0xffff0200, /* ps_2_0 */
14976 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
14977 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14978 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14979 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14980 0x0000ffff, /* end */
14983 static const struct
14985 float x, y, z;
14986 float u, v;
14988 quad[] =
14990 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14991 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14992 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14993 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14996 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14997 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14998 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14999 ok(!!d3d, "Failed to create a D3D object.\n");
15000 if (!(device = create_device(d3d, window, window, TRUE)))
15002 skip("Failed to create a D3D device, skipping tests.\n");
15003 goto done;
15006 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15007 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15008 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15010 skip("No ps_2_0 support, skipping tests.\n");
15011 IDirect3DDevice9_Release(device);
15012 goto done;
15014 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15016 skip("No cube / volume texture support, skipping tests.\n");
15017 IDirect3DDevice9_Release(device);
15018 goto done;
15021 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15022 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15024 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15025 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15026 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15027 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15028 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15029 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15031 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15032 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15034 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15035 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15037 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15038 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15043 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15044 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15046 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15047 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15049 hr = IDirect3DDevice9_BeginScene(device);
15050 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15051 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15052 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15053 hr = IDirect3DDevice9_EndScene(device);
15054 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15056 color = getPixelColorFromSurface(rt, 32, 32);
15057 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15059 /* Now try with a cube texture */
15060 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15061 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15063 hr = IDirect3DDevice9_BeginScene(device);
15064 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15066 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15067 hr = IDirect3DDevice9_EndScene(device);
15068 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15070 color = getPixelColorFromSurface(rt, 32, 32);
15071 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15073 /* And then with a volume texture */
15074 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15075 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15077 hr = IDirect3DDevice9_BeginScene(device);
15078 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15080 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15081 hr = IDirect3DDevice9_EndScene(device);
15082 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15084 color = getPixelColorFromSurface(rt, 32, 32);
15085 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15087 IDirect3DSurface9_Release(rt);
15088 IDirect3DSurface9_Release(old_rt);
15089 IDirect3DPixelShader9_Release(ps);
15090 IDirect3DPixelShader9_Release(ps_cube);
15091 IDirect3DPixelShader9_Release(ps_volume);
15092 refcount = IDirect3DDevice9_Release(device);
15093 ok(!refcount, "Device has %u references left.\n", refcount);
15094 done:
15095 IDirect3D9_Release(d3d);
15096 DestroyWindow(window);
15099 static void update_surface_test(void)
15101 static const BYTE blocks[][8] =
15103 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15104 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15105 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15106 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15107 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15108 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15109 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15111 static const struct
15113 UINT x, y;
15114 D3DCOLOR color;
15116 expected_colors[] =
15118 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15119 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15120 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15121 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15122 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15123 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15124 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15126 static const struct
15128 float x, y, z, w;
15129 float u, v;
15131 tri[] =
15133 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15134 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15135 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15137 static const RECT rect_2x2 = {0, 0, 2, 2};
15138 static const struct
15140 UINT src_level;
15141 UINT dst_level;
15142 const RECT *r;
15143 HRESULT hr;
15145 block_size_tests[] =
15147 {1, 0, NULL, D3D_OK},
15148 {0, 1, NULL, D3DERR_INVALIDCALL},
15149 {5, 4, NULL, D3DERR_INVALIDCALL},
15150 {4, 5, NULL, D3DERR_INVALIDCALL},
15151 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15152 {5, 5, &rect_2x2, D3D_OK},
15155 IDirect3DSurface9 *src_surface, *dst_surface;
15156 IDirect3DTexture9 *src_tex, *dst_tex;
15157 IDirect3DDevice9 *device;
15158 IDirect3D9 *d3d;
15159 ULONG refcount;
15160 UINT count, i;
15161 HWND window;
15162 HRESULT hr;
15164 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15165 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15166 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15167 ok(!!d3d, "Failed to create a D3D object.\n");
15168 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15169 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15171 skip("DXT1 not supported, skipping tests.\n");
15172 goto done;
15174 if (!(device = create_device(d3d, window, window, TRUE)))
15176 skip("Failed to create a D3D device, skipping tests.\n");
15177 goto done;
15180 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15181 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15182 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15183 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15185 count = IDirect3DTexture9_GetLevelCount(src_tex);
15186 ok(count == 7, "Got level count %u, expected 7.\n", count);
15188 for (i = 0; i < count; ++i)
15190 UINT row_count, block_count, x, y;
15191 D3DSURFACE_DESC desc;
15192 BYTE *row, *block;
15193 D3DLOCKED_RECT r;
15195 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15196 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15198 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15199 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15201 row_count = ((desc.Height + 3) & ~3) / 4;
15202 block_count = ((desc.Width + 3) & ~3) / 4;
15203 row = r.pBits;
15205 for (y = 0; y < row_count; ++y)
15207 block = row;
15208 for (x = 0; x < block_count; ++x)
15210 memcpy(block, blocks[i], sizeof(blocks[i]));
15211 block += sizeof(blocks[i]);
15213 row += r.Pitch;
15216 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15217 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15220 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15222 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15223 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15224 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15225 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15227 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15228 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15229 hr, i, block_size_tests[i].hr);
15231 IDirect3DSurface9_Release(dst_surface);
15232 IDirect3DSurface9_Release(src_surface);
15235 for (i = 0; i < count; ++i)
15237 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15238 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15239 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15240 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15242 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15243 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15245 IDirect3DSurface9_Release(dst_surface);
15246 IDirect3DSurface9_Release(src_surface);
15249 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15250 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15251 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15252 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15253 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15254 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15255 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15256 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15257 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15258 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15259 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15260 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15263 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15265 hr = IDirect3DDevice9_BeginScene(device);
15266 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15268 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15269 hr = IDirect3DDevice9_EndScene(device);
15270 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15272 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15274 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15275 ok(color_match(color, expected_colors[i].color, 0),
15276 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15277 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15280 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15281 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15283 IDirect3DTexture9_Release(dst_tex);
15284 IDirect3DTexture9_Release(src_tex);
15285 refcount = IDirect3DDevice9_Release(device);
15286 ok(!refcount, "Device has %u references left.\n", refcount);
15287 done:
15288 IDirect3D9_Release(d3d);
15289 DestroyWindow(window);
15292 static void multisample_get_rtdata_test(void)
15294 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15295 IDirect3DDevice9 *device;
15296 IDirect3D9 *d3d;
15297 ULONG refcount;
15298 HWND window;
15299 HRESULT hr;
15301 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15302 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15303 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15304 ok(!!d3d, "Failed to create a D3D object.\n");
15305 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15306 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15308 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15309 goto done;
15311 if (!(device = create_device(d3d, window, window, TRUE)))
15313 skip("Failed to create a D3D device, skipping tests.\n");
15314 goto done;
15317 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15318 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15319 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15320 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15321 D3DPOOL_SYSTEMMEM, &readback, NULL);
15322 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15324 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15325 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15326 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15327 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15329 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15330 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15331 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15332 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15334 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15335 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15336 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15337 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15339 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15340 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15341 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15342 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15344 IDirect3DSurface9_Release(original_ds);
15345 IDirect3DSurface9_Release(original_rt);
15346 IDirect3DSurface9_Release(readback);
15347 IDirect3DSurface9_Release(rt);
15348 refcount = IDirect3DDevice9_Release(device);
15349 ok(!refcount, "Device has %u references left.\n", refcount);
15350 done:
15351 IDirect3D9_Release(d3d);
15352 DestroyWindow(window);
15355 static void multisampled_depth_buffer_test(void)
15357 IDirect3DDevice9 *device = 0;
15358 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15359 IDirect3D9 *d3d;
15360 D3DCAPS9 caps;
15361 HRESULT hr;
15362 D3DPRESENT_PARAMETERS present_parameters;
15363 unsigned int i;
15364 static const struct
15366 float x, y, z;
15367 D3DCOLOR color;
15369 quad_1[] =
15371 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15372 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15373 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15374 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15376 quad_2[] =
15378 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15379 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15380 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15381 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15383 static const struct
15385 UINT x, y;
15386 D3DCOLOR color;
15388 expected_colors[] =
15390 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15391 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15392 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15393 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15394 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15395 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15396 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15397 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15400 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15401 ok(!!d3d, "Failed to create a D3D object.\n");
15403 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15404 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15406 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15407 IDirect3D9_Release(d3d);
15408 return;
15410 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15411 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15413 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15414 IDirect3D9_Release(d3d);
15415 return;
15418 ZeroMemory(&present_parameters, sizeof(present_parameters));
15419 present_parameters.Windowed = TRUE;
15420 present_parameters.hDeviceWindow = create_window();
15421 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15422 present_parameters.BackBufferWidth = 640;
15423 present_parameters.BackBufferHeight = 480;
15424 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15425 present_parameters.EnableAutoDepthStencil = TRUE;
15426 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15427 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15429 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15430 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15431 &present_parameters, &device);
15432 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15434 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15435 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15436 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15438 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15439 goto cleanup;
15442 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15443 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15444 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15445 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15446 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15447 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15449 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15450 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15451 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15452 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15455 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15457 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15458 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15459 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15461 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15462 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15463 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15465 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15466 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15468 /* Render onscreen and then offscreen */
15469 hr = IDirect3DDevice9_BeginScene(device);
15470 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15472 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15473 hr = IDirect3DDevice9_EndScene(device);
15474 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15476 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15477 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15478 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15479 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15481 hr = IDirect3DDevice9_BeginScene(device);
15482 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15484 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15485 hr = IDirect3DDevice9_EndScene(device);
15486 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15488 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15489 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15491 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15493 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15494 ok(color_match(color, expected_colors[i].color, 1),
15495 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15496 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15499 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15500 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15501 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15502 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15504 /* Render offscreen and then onscreen */
15505 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15506 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15507 IDirect3DSurface9_Release(ds);
15508 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15509 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15510 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15511 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15512 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15514 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15515 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15517 hr = IDirect3DDevice9_BeginScene(device);
15518 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15520 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15521 hr = IDirect3DDevice9_EndScene(device);
15522 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15524 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15525 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15526 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15527 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15529 hr = IDirect3DDevice9_BeginScene(device);
15530 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15532 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15533 hr = IDirect3DDevice9_EndScene(device);
15534 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15536 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15537 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15539 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15541 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15542 ok(color_match(color, expected_colors[i].color, 1),
15543 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15544 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15547 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15548 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15550 IDirect3DSurface9_Release(ds);
15551 IDirect3DSurface9_Release(readback);
15552 IDirect3DSurface9_Release(rt);
15553 IDirect3DSurface9_Release(original_rt);
15554 cleanup_device(device);
15556 ZeroMemory(&present_parameters, sizeof(present_parameters));
15557 present_parameters.Windowed = TRUE;
15558 present_parameters.hDeviceWindow = create_window();
15559 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15560 present_parameters.BackBufferWidth = 640;
15561 present_parameters.BackBufferHeight = 480;
15562 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15563 present_parameters.EnableAutoDepthStencil = TRUE;
15564 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15565 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15567 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15568 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15569 &present_parameters, &device);
15570 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15572 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15573 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15575 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15576 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15577 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15578 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15579 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15580 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15581 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15582 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15583 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15585 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15586 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15587 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15588 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15589 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15590 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15591 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15592 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15595 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15596 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15597 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15598 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15599 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15601 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15602 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15603 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15605 /* Render to a multisampled offscreen frame buffer and then blit to
15606 * the onscreen (not multisampled) frame buffer. */
15607 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15608 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15610 hr = IDirect3DDevice9_BeginScene(device);
15611 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15612 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15613 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15614 hr = IDirect3DDevice9_EndScene(device);
15615 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15617 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15618 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15619 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
15620 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15622 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15623 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15624 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15625 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15627 hr = IDirect3DDevice9_BeginScene(device);
15628 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15630 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15631 hr = IDirect3DDevice9_EndScene(device);
15632 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15634 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15635 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15637 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15639 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15640 ok(color_match(color, expected_colors[i].color, 1),
15641 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15642 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15645 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15646 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15648 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15649 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15650 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15651 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15653 IDirect3DSurface9_Release(original_ds);
15654 IDirect3DSurface9_Release(original_rt);
15655 IDirect3DSurface9_Release(ds);
15656 IDirect3DSurface9_Release(readback);
15657 IDirect3DSurface9_Release(rt);
15658 cleanup:
15659 cleanup_device(device);
15660 IDirect3D9_Release(d3d);
15663 static void resz_test(void)
15665 IDirect3DDevice9 *device = 0;
15666 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
15667 D3DCAPS9 caps;
15668 HRESULT hr;
15669 D3DPRESENT_PARAMETERS present_parameters;
15670 unsigned int i;
15671 static const DWORD ps_code[] =
15673 0xffff0200, /* ps_2_0 */
15674 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15675 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15676 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
15677 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
15678 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15679 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
15680 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
15681 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
15682 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
15683 0x0000ffff, /* end */
15685 struct
15687 float x, y, z;
15688 float s, t, p, q;
15690 quad[] =
15692 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15693 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15694 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15695 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15697 struct
15699 UINT x, y;
15700 D3DCOLOR color;
15702 expected_colors[] =
15704 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15705 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15706 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15707 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15708 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15709 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15710 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15711 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15713 IDirect3DTexture9 *texture;
15714 IDirect3DPixelShader9 *ps;
15715 IDirect3D9 *d3d;
15716 DWORD value;
15718 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15719 ok(!!d3d, "Failed to create a D3D object.\n");
15721 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15722 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15724 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
15725 IDirect3D9_Release(d3d);
15726 return;
15728 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15729 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15731 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
15732 IDirect3D9_Release(d3d);
15733 return;
15736 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15737 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
15739 skip("No INTZ support, skipping RESZ test.\n");
15740 IDirect3D9_Release(d3d);
15741 return;
15744 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15745 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
15747 skip("No RESZ support, skipping RESZ test.\n");
15748 IDirect3D9_Release(d3d);
15749 return;
15752 ZeroMemory(&present_parameters, sizeof(present_parameters));
15753 present_parameters.Windowed = TRUE;
15754 present_parameters.hDeviceWindow = create_window();
15755 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15756 present_parameters.BackBufferWidth = 640;
15757 present_parameters.BackBufferHeight = 480;
15758 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15759 present_parameters.EnableAutoDepthStencil = FALSE;
15760 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15761 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15763 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15764 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15765 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15767 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15768 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15769 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15771 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
15772 cleanup_device(device);
15773 IDirect3D9_Release(d3d);
15774 return;
15776 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15778 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
15779 cleanup_device(device);
15780 IDirect3D9_Release(d3d);
15781 return;
15784 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15785 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15787 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15788 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15789 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15790 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15791 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15792 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15793 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15794 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15795 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15797 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15798 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15799 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15800 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15801 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15802 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15803 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15804 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15805 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15806 IDirect3DSurface9_Release(intz_ds);
15807 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15808 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15810 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15811 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15815 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15817 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15819 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15822 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15823 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15824 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15825 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15826 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15827 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15828 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15829 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15830 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15832 /* Render offscreen (multisampled), blit the depth buffer
15833 * into the INTZ texture and then check its contents */
15834 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15835 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15836 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15837 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15839 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15841 hr = IDirect3DDevice9_BeginScene(device);
15842 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15843 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15844 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15846 /* The destination depth texture has to be bound to sampler 0 */
15847 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15848 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15850 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
15851 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15852 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15854 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15856 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15857 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15858 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15860 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15862 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15864 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15866 /* The actual multisampled depth buffer resolve happens here */
15867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15868 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15869 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15870 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15872 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15873 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15874 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15875 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15876 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15877 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15879 /* Read the depth values back */
15880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15881 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15882 hr = IDirect3DDevice9_EndScene(device);
15883 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15885 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15887 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15888 ok(color_match(color, expected_colors[i].color, 1),
15889 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15890 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15894 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15896 IDirect3DSurface9_Release(ds);
15897 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15898 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15899 IDirect3DTexture9_Release(texture);
15900 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15901 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15902 IDirect3DPixelShader9_Release(ps);
15903 IDirect3DSurface9_Release(readback);
15904 IDirect3DSurface9_Release(original_rt);
15905 IDirect3DSurface9_Release(rt);
15906 cleanup_device(device);
15908 ZeroMemory(&present_parameters, sizeof(present_parameters));
15909 present_parameters.Windowed = TRUE;
15910 present_parameters.hDeviceWindow = create_window();
15911 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15912 present_parameters.BackBufferWidth = 640;
15913 present_parameters.BackBufferHeight = 480;
15914 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15915 present_parameters.EnableAutoDepthStencil = TRUE;
15916 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15917 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15919 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15920 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15921 ok(hr == D3D_OK, "Failed to create a device, 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, &ds);
15926 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15927 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15928 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15929 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15930 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15931 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15932 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15933 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15934 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15935 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15936 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15937 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15938 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15940 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15941 IDirect3DSurface9_Release(intz_ds);
15942 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15943 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15946 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15948 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15950 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15952 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15953 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15954 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15956 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15957 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15958 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15959 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15960 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15961 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15962 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15963 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15964 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15965 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15967 /* Render onscreen, blit the depth buffer into the INTZ texture
15968 * and then check its contents */
15969 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15970 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15971 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15972 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15973 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15974 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15976 hr = IDirect3DDevice9_BeginScene(device);
15977 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15979 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15980 hr = IDirect3DDevice9_EndScene(device);
15981 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15983 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15984 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15987 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15989 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15991 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15995 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15997 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15999 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16001 /* The actual multisampled depth buffer resolve happens here */
16002 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16003 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16004 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16005 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16007 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16008 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16009 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16010 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16011 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16012 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16014 /* Read the depth values back */
16015 hr = IDirect3DDevice9_BeginScene(device);
16016 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16018 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16019 hr = IDirect3DDevice9_EndScene(device);
16020 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16022 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16024 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16025 ok(color_match(color, expected_colors[i].color, 1),
16026 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16027 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16030 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16031 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16034 /* Test edge cases - try with no texture at all */
16035 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16036 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16037 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16038 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16039 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16040 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16041 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16042 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16044 hr = IDirect3DDevice9_BeginScene(device);
16045 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16046 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16047 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16048 hr = IDirect3DDevice9_EndScene(device);
16049 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16052 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16054 /* With a non-multisampled depth buffer */
16055 IDirect3DSurface9_Release(ds);
16056 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16057 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16059 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16060 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16061 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16062 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16063 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16064 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16066 hr = IDirect3DDevice9_BeginScene(device);
16067 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16069 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16071 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16072 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16075 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16077 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16079 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16081 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16083 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16085 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16087 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16088 hr = IDirect3DDevice9_EndScene(device);
16089 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16092 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16094 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16095 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16097 /* Read the depth values back. */
16098 hr = IDirect3DDevice9_BeginScene(device);
16099 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16101 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16102 hr = IDirect3DDevice9_EndScene(device);
16103 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16105 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16107 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16108 ok(color_match(color, expected_colors[i].color, 1),
16109 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16110 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16113 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16114 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16116 /* Without a current depth-stencil buffer set */
16117 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16118 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16119 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16120 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16122 hr = IDirect3DDevice9_BeginScene(device);
16123 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16125 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16126 hr = IDirect3DDevice9_EndScene(device);
16127 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16130 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16132 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16133 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16134 IDirect3DSurface9_Release(ds);
16135 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16136 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16137 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16138 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16139 IDirect3DTexture9_Release(texture);
16140 IDirect3DPixelShader9_Release(ps);
16141 IDirect3DSurface9_Release(readback);
16142 IDirect3DSurface9_Release(original_rt);
16143 cleanup_device(device);
16144 IDirect3D9_Release(d3d);
16147 static void zenable_test(void)
16149 static const struct
16151 struct vec4 position;
16152 D3DCOLOR diffuse;
16154 tquad[] =
16156 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16157 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16158 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16159 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16161 IDirect3DDevice9 *device;
16162 IDirect3D9 *d3d;
16163 D3DCOLOR color;
16164 ULONG refcount;
16165 D3DCAPS9 caps;
16166 HWND window;
16167 HRESULT hr;
16168 UINT x, y;
16169 UINT i, j;
16170 UINT test;
16171 IDirect3DSurface9 *ds;
16173 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16174 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16175 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16176 ok(!!d3d, "Failed to create a D3D object.\n");
16177 if (!(device = create_device(d3d, window, window, TRUE)))
16179 skip("Failed to create a D3D device, skipping tests.\n");
16180 goto done;
16183 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16184 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16186 for (test = 0; test < 2; ++test)
16188 /* The Windows 8 testbot (WARP) appears to clip with
16189 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16190 static const D3DCOLOR expected_broken[] =
16192 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16193 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16194 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16195 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16198 if (!test)
16200 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16201 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16203 else
16205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16206 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16207 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16208 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16210 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16212 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16213 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16216 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16217 hr = IDirect3DDevice9_BeginScene(device);
16218 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16220 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16221 hr = IDirect3DDevice9_EndScene(device);
16222 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16224 for (i = 0; i < 4; ++i)
16226 for (j = 0; j < 4; ++j)
16228 x = 80 * ((2 * j) + 1);
16229 y = 60 * ((2 * i) + 1);
16230 color = getPixelColor(device, x, y);
16231 ok(color_match(color, 0x0000ff00, 1)
16232 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16233 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16234 x, y, color, test);
16238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16239 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16242 IDirect3DSurface9_Release(ds);
16244 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16245 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16247 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16248 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16250 static const DWORD vs_code[] =
16252 0xfffe0101, /* vs_1_1 */
16253 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16254 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16255 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16256 0x0000ffff
16258 static const DWORD ps_code[] =
16260 0xffff0101, /* ps_1_1 */
16261 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16262 0x0000ffff /* end */
16264 static const struct vec3 quad[] =
16266 {-1.0f, -1.0f, -0.5f},
16267 {-1.0f, 1.0f, -0.5f},
16268 { 1.0f, -1.0f, 1.5f},
16269 { 1.0f, 1.0f, 1.5f},
16271 static const D3DCOLOR expected[] =
16273 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16274 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16275 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16276 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16278 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16279 * vertices either. */
16280 static const D3DCOLOR expected_broken[] =
16282 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16283 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16284 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16285 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16288 IDirect3DVertexShader9 *vs;
16289 IDirect3DPixelShader9 *ps;
16291 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16292 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16293 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16294 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16295 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16296 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16297 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16298 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16299 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16300 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16303 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16304 hr = IDirect3DDevice9_BeginScene(device);
16305 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16308 hr = IDirect3DDevice9_EndScene(device);
16309 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16311 for (i = 0; i < 4; ++i)
16313 for (j = 0; j < 4; ++j)
16315 x = 80 * ((2 * j) + 1);
16316 y = 60 * ((2 * i) + 1);
16317 color = getPixelColor(device, x, y);
16318 ok(color_match(color, expected[i * 4 + j], 1)
16319 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16320 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16324 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16325 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16327 IDirect3DPixelShader9_Release(ps);
16328 IDirect3DVertexShader9_Release(vs);
16331 refcount = IDirect3DDevice9_Release(device);
16332 ok(!refcount, "Device has %u references left.\n", refcount);
16333 done:
16334 IDirect3D9_Release(d3d);
16335 DestroyWindow(window);
16338 static void fog_special_test(void)
16340 static const struct
16342 struct vec3 position;
16343 D3DCOLOR diffuse;
16345 quad[] =
16347 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16348 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16349 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16350 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16352 static const struct
16354 DWORD vertexmode, tablemode;
16355 BOOL vs, ps;
16356 D3DCOLOR color_left, color_right;
16358 tests[] =
16360 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16361 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16362 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16363 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16365 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16366 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16367 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16368 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16370 static const DWORD pixel_shader_code[] =
16372 0xffff0101, /* ps_1_1 */
16373 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16374 0x0000ffff
16376 static const DWORD vertex_shader_code[] =
16378 0xfffe0101, /* vs_1_1 */
16379 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16380 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16381 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16382 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16383 0x0000ffff
16385 static const D3DMATRIX identity =
16387 1.0f, 0.0f, 0.0f, 0.0f,
16388 0.0f, 1.0f, 0.0f, 0.0f,
16389 0.0f, 0.0f, 1.0f, 0.0f,
16390 0.0f, 0.0f, 0.0f, 1.0f,
16391 }}};
16392 union
16394 float f;
16395 DWORD d;
16396 } conv;
16397 DWORD color;
16398 HRESULT hr;
16399 unsigned int i;
16400 IDirect3DPixelShader9 *ps;
16401 IDirect3DVertexShader9 *vs;
16402 IDirect3DDevice9 *device;
16403 IDirect3D9 *d3d;
16404 ULONG refcount;
16405 D3DCAPS9 caps;
16406 HWND window;
16408 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16409 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16410 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16411 ok(!!d3d, "Failed to create a D3D object.\n");
16412 if (!(device = create_device(d3d, window, window, TRUE)))
16414 skip("Failed to create a D3D device, skipping tests.\n");
16415 goto done;
16418 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16419 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16420 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16422 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16423 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16425 else
16427 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16428 vs = NULL;
16430 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16432 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16433 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16435 else
16437 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16438 ps = NULL;
16441 /* The table fog tests seem to depend on the projection matrix explicitly
16442 * being set to an identity matrix, even though that's the default.
16443 * (AMD Radeon HD 6310, Windows 7) */
16444 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16445 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16447 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16448 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16450 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16452 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16454 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16456 conv.f = 0.5f;
16457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16458 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16460 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16462 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16464 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16465 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16467 if (!tests[i].vs)
16469 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16470 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16472 else if (vs)
16474 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16475 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16477 else
16479 continue;
16482 if (!tests[i].ps)
16484 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16485 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16487 else if (ps)
16489 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16490 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16492 else
16494 continue;
16497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16498 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16500 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16502 hr = IDirect3DDevice9_BeginScene(device);
16503 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16505 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16506 hr = IDirect3DDevice9_EndScene(device);
16507 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16509 color = getPixelColor(device, 310, 240);
16510 ok(color_match(color, tests[i].color_left, 1),
16511 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16512 color = getPixelColor(device, 330, 240);
16513 ok(color_match(color, tests[i].color_right, 1),
16514 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16516 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16517 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16520 if (vs)
16521 IDirect3DVertexShader9_Release(vs);
16522 if (ps)
16523 IDirect3DPixelShader9_Release(ps);
16524 refcount = IDirect3DDevice9_Release(device);
16525 ok(!refcount, "Device has %u references left.\n", refcount);
16526 done:
16527 IDirect3D9_Release(d3d);
16528 DestroyWindow(window);
16531 static void volume_srgb_test(void)
16533 HRESULT hr;
16534 unsigned int i, j;
16535 IDirect3DVolumeTexture9 *tex1, *tex2;
16536 D3DPOOL pool;
16537 D3DLOCKED_BOX locked_box;
16538 IDirect3DDevice9 *device;
16539 IDirect3D9 *d3d;
16540 D3DCOLOR color;
16541 ULONG refcount;
16542 HWND window;
16544 static const struct
16546 BOOL srgb;
16547 DWORD color;
16549 tests[] =
16551 /* Try toggling on and off */
16552 { FALSE, 0x007f7f7f },
16553 { TRUE, 0x00363636 },
16554 { FALSE, 0x007f7f7f },
16556 static const struct
16558 struct vec3 pos;
16559 struct vec3 texcrd;
16561 quad[] =
16563 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16564 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16565 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16566 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16569 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16570 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16571 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16572 ok(!!d3d, "Failed to create a D3D object.\n");
16573 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16574 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16576 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16577 goto done;
16579 if (!(device = create_device(d3d, window, window, TRUE)))
16581 skip("Failed to create a D3D device, skipping tests.\n");
16582 goto done;
16585 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16586 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16587 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16588 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16589 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16590 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16591 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16592 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16594 for (i = 0; i < 2; i++)
16596 if (!i)
16597 pool = D3DPOOL_SYSTEMMEM;
16598 else
16599 pool = D3DPOOL_MANAGED;
16601 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
16602 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16603 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
16604 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16605 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
16606 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
16607 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16609 if (!i)
16611 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
16612 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
16613 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16614 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
16615 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16616 IDirect3DVolumeTexture9_Release(tex1);
16618 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
16619 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16620 IDirect3DVolumeTexture9_Release(tex2);
16622 else
16624 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
16625 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16626 IDirect3DVolumeTexture9_Release(tex1);
16629 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
16631 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
16632 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
16634 hr = IDirect3DDevice9_BeginScene(device);
16635 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16637 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16638 hr = IDirect3DDevice9_EndScene(device);
16639 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16641 color = getPixelColor(device, 320, 240);
16642 ok(color_match(color, tests[j].color, 2),
16643 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
16645 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16646 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16650 refcount = IDirect3DDevice9_Release(device);
16651 ok(!refcount, "Device has %u references left.\n", refcount);
16652 done:
16653 IDirect3D9_Release(d3d);
16654 DestroyWindow(window);
16657 static void volume_dxt5_test(void)
16659 IDirect3DVolumeTexture9 *texture;
16660 IDirect3DDevice9 *device;
16661 D3DLOCKED_BOX box;
16662 IDirect3D9 *d3d;
16663 unsigned int i;
16664 ULONG refcount;
16665 DWORD color;
16666 HWND window;
16667 HRESULT hr;
16669 static const char texture_data[] =
16671 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
16672 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
16673 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
16674 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
16675 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
16677 static const struct
16679 struct vec3 position;
16680 struct vec3 texcrd;
16682 quads[] =
16684 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16685 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16686 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16687 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16689 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16690 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16691 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16692 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16694 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
16696 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16697 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16698 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16699 ok(!!d3d, "Failed to create a D3D object.\n");
16700 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16701 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
16703 skip("DXT5 volume textures are not supported, skipping test.\n");
16704 goto done;
16706 if (!(device = create_device(d3d, window, window, TRUE)))
16708 skip("Failed to create a D3D device, skipping tests.\n");
16709 goto done;
16712 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
16713 D3DPOOL_MANAGED, &texture, NULL);
16714 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16716 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16717 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16718 memcpy(box.pBits, texture_data, sizeof(texture_data));
16719 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16720 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16722 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16723 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16724 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16725 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16726 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16727 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16729 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16730 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16731 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16732 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16733 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
16735 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16736 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16737 hr = IDirect3DDevice9_BeginScene(device);
16738 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16740 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16741 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16742 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16743 hr = IDirect3DDevice9_EndScene(device);
16744 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16746 for (i = 0; i < 4; i++)
16748 color = getPixelColor(device, 80 + 160 * i, 240);
16749 ok (color_match(color, expected_colors[i], 1),
16750 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
16753 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16754 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16755 IDirect3DVolumeTexture9_Release(texture);
16756 refcount = IDirect3DDevice9_Release(device);
16757 ok(!refcount, "Device has %u references left.\n", refcount);
16758 done:
16759 IDirect3D9_Release(d3d);
16760 DestroyWindow(window);
16763 static void volume_v16u16_test(void)
16765 IDirect3DVolumeTexture9 *texture;
16766 IDirect3DPixelShader9 *shader;
16767 IDirect3DDevice9 *device;
16768 D3DLOCKED_BOX box;
16769 IDirect3D9 *d3d;
16770 unsigned int i;
16771 ULONG refcount;
16772 D3DCAPS9 caps;
16773 SHORT *texel;
16774 DWORD color;
16775 HWND window;
16776 HRESULT hr;
16778 static const struct
16780 struct vec3 position;
16781 struct vec3 texcrd;
16783 quads[] =
16785 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16786 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16787 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16788 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16790 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16791 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16792 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16793 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16795 static const DWORD shader_code[] =
16797 0xffff0101, /* ps_1_1 */
16798 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
16799 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
16800 0x00000042, 0xb00f0000, /* tex t0 */
16801 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
16802 0x0000ffff /* end */
16805 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16806 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16807 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16808 ok(!!d3d, "Failed to create a D3D object.\n");
16809 if (!(device = create_device(d3d, window, window, TRUE)))
16811 skip("Failed to create a D3D device, skipping tests.\n");
16812 goto done;
16815 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16816 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16817 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
16819 skip("No ps_1_1 support, skipping tests.\n");
16820 IDirect3DDevice9_Release(device);
16821 goto done;
16823 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16824 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
16826 skip("Volume V16U16 textures are not supported, skipping test.\n");
16827 IDirect3DDevice9_Release(device);
16828 goto done;
16831 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16832 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16833 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
16834 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16835 hr = IDirect3DDevice9_SetPixelShader(device, shader);
16836 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16837 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16838 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
16840 for (i = 0; i < 2; i++)
16842 D3DPOOL pool;
16844 if (i)
16845 pool = D3DPOOL_SYSTEMMEM;
16846 else
16847 pool = D3DPOOL_MANAGED;
16849 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16850 pool, &texture, NULL);
16851 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16853 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16854 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16856 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
16857 texel[0] = 32767;
16858 texel[1] = 32767;
16859 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
16860 texel[0] = -32768;
16861 texel[1] = 0;
16862 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
16863 texel[0] = -16384;
16864 texel[1] = 16384;
16865 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
16866 texel[0] = 0;
16867 texel[1] = 0;
16869 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16870 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16872 if (i)
16874 IDirect3DVolumeTexture9 *texture2;
16876 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16877 D3DPOOL_DEFAULT, &texture2, NULL);
16878 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16880 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
16881 (IDirect3DBaseTexture9 *)texture2);
16882 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16884 IDirect3DVolumeTexture9_Release(texture);
16885 texture = texture2;
16888 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
16889 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16891 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16892 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16893 hr = IDirect3DDevice9_BeginScene(device);
16894 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16896 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16898 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16899 hr = IDirect3DDevice9_EndScene(device);
16900 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16902 color = getPixelColor(device, 120, 160);
16903 ok (color_match(color, 0x000080ff, 2),
16904 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
16905 color = getPixelColor(device, 120, 400);
16906 ok (color_match(color, 0x00ffffff, 2),
16907 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
16908 color = getPixelColor(device, 360, 160);
16909 ok (color_match(color, 0x007f7fff, 2),
16910 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
16911 color = getPixelColor(device, 360, 400);
16912 ok (color_match(color, 0x0040c0ff, 2),
16913 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
16915 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16916 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16918 IDirect3DVolumeTexture9_Release(texture);
16921 IDirect3DPixelShader9_Release(shader);
16922 refcount = IDirect3DDevice9_Release(device);
16923 ok(!refcount, "Device has %u references left.\n", refcount);
16924 done:
16925 IDirect3D9_Release(d3d);
16926 DestroyWindow(window);
16929 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
16931 HRESULT hr;
16932 static const struct
16934 struct vec3 position;
16935 struct vec2 texcoord;
16937 quad[] =
16939 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
16940 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
16941 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
16942 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
16945 hr = IDirect3DDevice9_BeginScene(device);
16946 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
16948 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16949 hr = IDirect3DDevice9_EndScene(device);
16950 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16953 static void add_dirty_rect_test(void)
16955 HRESULT hr;
16956 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
16957 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
16958 IDirect3DDevice9 *device;
16959 IDirect3D9 *d3d;
16960 unsigned int i;
16961 ULONG refcount;
16962 DWORD *texel;
16963 HWND window;
16964 D3DLOCKED_RECT locked_rect;
16965 static const RECT part_rect = {96, 96, 160, 160};
16966 DWORD color;
16968 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16969 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16970 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16971 ok(!!d3d, "Failed to create a D3D object.\n");
16972 if (!(device = create_device(d3d, window, window, TRUE)))
16974 skip("Failed to create a D3D device, skipping tests.\n");
16975 IDirect3D9_Release(d3d);
16976 DestroyWindow(window);
16977 return;
16980 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16981 D3DPOOL_DEFAULT, &tex_dst1, NULL);
16982 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16983 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16984 D3DPOOL_DEFAULT, &tex_dst2, NULL);
16985 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16986 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16987 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
16988 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16989 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16990 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
16991 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16992 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16993 D3DPOOL_MANAGED, &tex_managed, NULL);
16994 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16996 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
16997 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16998 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
16999 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17000 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17001 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17002 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17003 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17005 fill_surface(surface_src_red, 0x00ff0000, 0);
17006 fill_surface(surface_src_green, 0x0000ff00, 0);
17008 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17009 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17010 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17011 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17012 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17013 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17015 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17016 (IDirect3DBaseTexture9 *)tex_dst1);
17017 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17019 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17020 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17021 (IDirect3DBaseTexture9 *)tex_dst2);
17022 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17023 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17024 (IDirect3DBaseTexture9 *)tex_dst2);
17025 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17027 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17028 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17029 add_dirty_rect_test_draw(device);
17030 color = getPixelColor(device, 320, 240);
17031 ok(color_match(color, 0x0000ff00, 1),
17032 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17033 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17034 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17036 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17037 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17038 add_dirty_rect_test_draw(device);
17039 color = getPixelColor(device, 320, 240);
17040 todo_wine ok(color_match(color, 0x00ff0000, 1),
17041 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17042 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17043 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17045 /* AddDirtyRect on the destination is ignored. */
17046 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17047 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17048 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17049 (IDirect3DBaseTexture9 *)tex_dst2);
17050 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17051 add_dirty_rect_test_draw(device);
17052 color = getPixelColor(device, 320, 240);
17053 todo_wine ok(color_match(color, 0x00ff0000, 1),
17054 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17055 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17056 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17058 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17059 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17060 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17061 (IDirect3DBaseTexture9 *)tex_dst2);
17062 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17063 add_dirty_rect_test_draw(device);
17064 color = getPixelColor(device, 320, 240);
17065 todo_wine ok(color_match(color, 0x00ff0000, 1),
17066 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17067 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17068 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17070 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17071 * tracking is supported. */
17072 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17073 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17074 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17075 (IDirect3DBaseTexture9 *)tex_dst2);
17076 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17077 add_dirty_rect_test_draw(device);
17078 color = getPixelColor(device, 320, 240);
17079 ok(color_match(color, 0x0000ff00, 1),
17080 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17081 color = getPixelColor(device, 1, 1);
17082 todo_wine ok(color_match(color, 0x00ff0000, 1),
17083 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17084 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17085 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17087 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17088 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17089 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17090 (IDirect3DBaseTexture9 *)tex_dst2);
17091 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17092 add_dirty_rect_test_draw(device);
17093 color = getPixelColor(device, 1, 1);
17094 ok(color_match(color, 0x0000ff00, 1),
17095 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17097 /* Locks with NO_DIRTY_UPDATE are ignored. */
17098 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17099 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17100 (IDirect3DBaseTexture9 *)tex_dst2);
17101 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17102 add_dirty_rect_test_draw(device);
17103 color = getPixelColor(device, 320, 240);
17104 todo_wine ok(color_match(color, 0x0000ff00, 1),
17105 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17106 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17107 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17109 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17110 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17111 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17112 (IDirect3DBaseTexture9 *)tex_dst2);
17113 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17114 add_dirty_rect_test_draw(device);
17115 color = getPixelColor(device, 320, 240);
17116 todo_wine ok(color_match(color, 0x0000ff00, 1),
17117 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17118 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17119 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17121 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17122 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17123 (IDirect3DBaseTexture9 *)tex_dst2);
17124 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17125 add_dirty_rect_test_draw(device);
17126 color = getPixelColor(device, 320, 240);
17127 ok(color_match(color, 0x000000ff, 1),
17128 "Expected color 0x000000ff, got 0x%08x.\n", color);
17129 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17130 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17132 /* Maps without either of these flags record a dirty rectangle. */
17133 fill_surface(surface_src_green, 0x00ffffff, 0);
17134 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17135 (IDirect3DBaseTexture9 *)tex_dst2);
17136 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17137 add_dirty_rect_test_draw(device);
17138 color = getPixelColor(device, 320, 240);
17139 ok(color_match(color, 0x00ffffff, 1),
17140 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17141 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17142 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17144 /* Partial LockRect works just like a partial AddDirtyRect call. */
17145 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17146 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17147 texel = locked_rect.pBits;
17148 for (i = 0; i < 64; i++)
17149 texel[i] = 0x00ff00ff;
17150 for (i = 1; i < 64; i++)
17151 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17152 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17153 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17154 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17155 (IDirect3DBaseTexture9 *)tex_dst2);
17156 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17157 add_dirty_rect_test_draw(device);
17158 color = getPixelColor(device, 320, 240);
17159 ok(color_match(color, 0x00ff00ff, 1),
17160 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17161 color = getPixelColor(device, 1, 1);
17162 ok(color_match(color, 0x00ffffff, 1),
17163 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17165 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17167 fill_surface(surface_src_red, 0x00ff0000, 0);
17168 fill_surface(surface_src_green, 0x0000ff00, 0);
17170 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17171 (IDirect3DBaseTexture9 *)tex_dst1);
17172 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17173 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17174 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17175 add_dirty_rect_test_draw(device);
17176 color = getPixelColor(device, 320, 240);
17177 ok(color_match(color, 0x0000ff00, 1),
17178 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17179 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17180 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17182 /* UpdateSurface ignores the missing dirty marker. */
17183 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17184 (IDirect3DBaseTexture9 *)tex_dst2);
17185 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17186 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17187 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17188 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17189 add_dirty_rect_test_draw(device);
17190 color = getPixelColor(device, 320, 240);
17191 ok(color_match(color, 0x0000ff00, 1),
17192 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17193 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17194 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17196 fill_surface(surface_managed, 0x00ff0000, 0);
17197 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17198 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17199 add_dirty_rect_test_draw(device);
17200 color = getPixelColor(device, 320, 240);
17201 ok(color_match(color, 0x00ff0000, 1),
17202 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17204 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17206 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17207 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17208 add_dirty_rect_test_draw(device);
17209 color = getPixelColor(device, 320, 240);
17210 ok(color_match(color, 0x00ff0000, 1),
17211 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17212 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17213 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17215 /* AddDirtyRect uploads the new contents.
17216 * Side note, not tested in the test: Partial surface updates work, and two separate
17217 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17218 * untested. */
17219 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17220 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17221 add_dirty_rect_test_draw(device);
17222 color = getPixelColor(device, 320, 240);
17223 ok(color_match(color, 0x0000ff00, 1),
17224 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17225 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17226 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17228 /* So does EvictManagedResources. */
17229 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17230 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17231 hr = IDirect3DDevice9_EvictManagedResources(device);
17232 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17233 add_dirty_rect_test_draw(device);
17234 color = getPixelColor(device, 320, 240);
17235 ok(color_match(color, 0x000000ff, 1),
17236 "Expected color 0x000000ff, got 0x%08x.\n", color);
17237 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17238 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17240 /* AddDirtyRect on a locked texture is allowed. */
17241 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17242 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17243 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17244 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17245 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17246 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17248 /* Redundant AddDirtyRect calls are ok. */
17249 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17250 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17251 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17252 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17254 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17255 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17256 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17257 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17258 IDirect3DSurface9_Release(surface_dst2);
17259 IDirect3DSurface9_Release(surface_managed);
17260 IDirect3DSurface9_Release(surface_src_red);
17261 IDirect3DSurface9_Release(surface_src_green);
17262 IDirect3DTexture9_Release(tex_src_red);
17263 IDirect3DTexture9_Release(tex_src_green);
17264 IDirect3DTexture9_Release(tex_dst1);
17265 IDirect3DTexture9_Release(tex_dst2);
17266 IDirect3DTexture9_Release(tex_managed);
17267 refcount = IDirect3DDevice9_Release(device);
17268 ok(!refcount, "Device has %u references left.\n", refcount);
17269 IDirect3D9_Release(d3d);
17270 DestroyWindow(window);
17273 static void test_per_stage_constant(void)
17275 IDirect3DDevice9 *device;
17276 IDirect3D9 *d3d;
17277 D3DCOLOR color;
17278 ULONG refcount;
17279 D3DCAPS9 caps;
17280 HWND window;
17281 HRESULT hr;
17283 static const struct
17285 struct vec3 position;
17286 D3DCOLOR diffuse;
17288 quad[] =
17290 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17291 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17292 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17293 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17296 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17297 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17298 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17299 ok(!!d3d, "Failed to create a D3D object.\n");
17300 if (!(device = create_device(d3d, window, window, TRUE)))
17302 skip("Failed to create a D3D device, skipping tests.\n");
17303 goto done;
17306 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17307 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17308 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17310 skip("Per-stage constants not supported, skipping tests.\n");
17311 IDirect3DDevice9_Release(device);
17312 goto done;
17315 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17316 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17318 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17320 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17322 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17324 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17326 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17327 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17328 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17329 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17330 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17331 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17334 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17336 hr = IDirect3DDevice9_BeginScene(device);
17337 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17339 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17340 hr = IDirect3DDevice9_EndScene(device);
17341 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17343 color = getPixelColor(device, 320, 240);
17344 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17345 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17346 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17348 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17349 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17351 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17352 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17354 hr = IDirect3DDevice9_BeginScene(device);
17355 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17356 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17357 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17358 hr = IDirect3DDevice9_EndScene(device);
17359 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17361 color = getPixelColor(device, 320, 240);
17362 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17363 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17364 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17366 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17367 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17370 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17372 hr = IDirect3DDevice9_BeginScene(device);
17373 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17375 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17376 hr = IDirect3DDevice9_EndScene(device);
17377 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17379 color = getPixelColor(device, 320, 240);
17380 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17381 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17382 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17384 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17385 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17386 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17387 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17388 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17389 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17391 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17392 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17394 hr = IDirect3DDevice9_BeginScene(device);
17395 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17397 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17398 hr = IDirect3DDevice9_EndScene(device);
17399 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17401 color = getPixelColor(device, 320, 240);
17402 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17403 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17404 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17406 refcount = IDirect3DDevice9_Release(device);
17407 ok(!refcount, "Device has %u references left.\n", refcount);
17408 done:
17409 IDirect3D9_Release(d3d);
17410 DestroyWindow(window);
17413 static void test_3dc_formats(void)
17415 static const char ati1n_data[] =
17417 /* A 4x4 texture with the color component at 50%. */
17418 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17420 static const char ati2n_data[] =
17422 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17423 * 0% second component. Second block is the opposite. */
17424 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17427 static const struct
17429 struct vec3 position;
17430 struct vec2 texcoord;
17432 quads[] =
17434 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17435 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17436 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17437 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17439 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17440 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17441 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17442 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17444 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17445 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17446 static const struct
17448 struct vec2 position;
17449 D3DCOLOR amd_r500;
17450 D3DCOLOR amd_r600;
17451 D3DCOLOR nvidia_old;
17452 D3DCOLOR nvidia_new;
17454 expected_colors[] =
17456 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17457 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17458 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17459 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17461 IDirect3D9 *d3d;
17462 IDirect3DDevice9 *device;
17463 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17464 D3DCAPS9 caps;
17465 D3DLOCKED_RECT rect;
17466 D3DCOLOR color;
17467 ULONG refcount;
17468 HWND window;
17469 HRESULT hr;
17470 unsigned int i;
17472 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17473 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17474 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17475 ok(!!d3d, "Failed to create a D3D object.\n");
17476 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17477 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17479 skip("ATI1N textures are not supported, skipping test.\n");
17480 goto done;
17482 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17483 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17485 skip("ATI2N textures are not supported, skipping test.\n");
17486 goto done;
17488 if (!(device = create_device(d3d, window, window, TRUE)))
17490 skip("Failed to create a D3D device, skipping tests.\n");
17491 goto done;
17493 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17494 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17495 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17497 skip("D3DTA_TEMP not supported, skipping tests.\n");
17498 IDirect3DDevice9_Release(device);
17499 goto done;
17502 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17503 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17504 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17506 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17507 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17508 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17509 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17510 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17512 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17513 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17514 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17516 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17517 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17518 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17519 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17520 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17522 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17523 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17524 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17525 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17526 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17527 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17528 /* The temporary register is initialized to 0. */
17529 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17530 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17531 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17532 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17533 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17534 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17535 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17536 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17537 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17538 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17540 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17541 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17542 hr = IDirect3DDevice9_BeginScene(device);
17543 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17544 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17545 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17546 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17547 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17548 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17549 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17550 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17551 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17552 hr = IDirect3DDevice9_EndScene(device);
17553 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17555 for (i = 0; i < 4; ++i)
17557 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17558 ok (color_match(color, expected_colors[i].amd_r500, 1)
17559 || color_match(color, expected_colors[i].amd_r600, 1)
17560 || color_match(color, expected_colors[i].nvidia_old, 1)
17561 || color_match(color, expected_colors[i].nvidia_new, 1),
17562 "Got unexpected color 0x%08x, case %u.\n", color, i);
17565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17566 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17567 IDirect3DTexture9_Release(ati2n_texture);
17568 IDirect3DTexture9_Release(ati1n_texture);
17569 refcount = IDirect3DDevice9_Release(device);
17570 ok(!refcount, "Device has %u references left.\n", refcount);
17572 done:
17573 IDirect3D9_Release(d3d);
17574 DestroyWindow(window);
17577 static void test_fog_interpolation(void)
17579 HRESULT hr;
17580 IDirect3DDevice9 *device;
17581 IDirect3D9 *d3d;
17582 ULONG refcount;
17583 HWND window;
17584 D3DCOLOR color;
17585 static const struct
17587 struct vec3 position;
17588 D3DCOLOR diffuse;
17589 D3DCOLOR specular;
17591 quad[] =
17593 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
17594 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
17595 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
17596 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
17598 union
17600 DWORD d;
17601 float f;
17602 } conv;
17603 unsigned int i;
17604 static const struct
17606 D3DFOGMODE vfog, tfog;
17607 D3DSHADEMODE shade;
17608 D3DCOLOR middle_color;
17609 BOOL todo;
17611 tests[] =
17613 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
17614 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
17615 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
17616 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
17617 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17618 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17619 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17620 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17622 static const D3DMATRIX ident_mat =
17624 1.0f, 0.0f, 0.0f, 0.0f,
17625 0.0f, 1.0f, 0.0f, 0.0f,
17626 0.0f, 0.0f, 1.0f, 0.0f,
17627 0.0f, 0.0f, 0.0f, 1.0f
17628 }}};
17629 D3DCAPS9 caps;
17631 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17632 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17633 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17634 ok(!!d3d, "Failed to create a D3D object.\n");
17636 if (!(device = create_device(d3d, window, window, TRUE)))
17638 skip("Failed to create a D3D device, skipping tests.\n");
17639 IDirect3D9_Release(d3d);
17640 DestroyWindow(window);
17641 return;
17644 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17645 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17646 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17647 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
17649 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
17650 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17652 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
17654 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17655 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17656 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17658 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17659 conv.f = 5.0;
17660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
17661 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17663 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17664 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17665 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
17666 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
17668 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17670 /* Some of the tests seem to depend on the projection matrix explicitly
17671 * being set to an identity matrix, even though that's the default.
17672 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
17673 * the drivers seem to use a static z = 1.0 input for the fog equation.
17674 * The input value is independent of the actual z and w component of
17675 * the vertex position. */
17676 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
17677 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17679 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17681 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
17682 continue;
17684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
17685 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
17688 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
17690 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
17692 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17693 hr = IDirect3DDevice9_BeginScene(device);
17694 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17696 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17697 hr = IDirect3DDevice9_EndScene(device);
17698 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17700 color = getPixelColor(device, 0, 240);
17701 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
17702 color = getPixelColor(device, 320, 240);
17703 if (tests[i].todo)
17704 todo_wine ok(color_match(color, tests[i].middle_color, 2),
17705 "Got unexpected color 0x%08x, case %u.\n", color, i);
17706 else
17707 ok(color_match(color, tests[i].middle_color, 2),
17708 "Got unexpected color 0x%08x, case %u.\n", color, i);
17709 color = getPixelColor(device, 639, 240);
17710 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
17711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17712 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17715 refcount = IDirect3DDevice9_Release(device);
17716 ok(!refcount, "Device has %u references left.\n", refcount);
17717 IDirect3D9_Release(d3d);
17718 DestroyWindow(window);
17721 static void test_negative_fixedfunction_fog(void)
17723 HRESULT hr;
17724 IDirect3DDevice9 *device;
17725 IDirect3D9 *d3d;
17726 ULONG refcount;
17727 HWND window;
17728 D3DCOLOR color;
17729 static const struct
17731 struct vec3 position;
17732 D3DCOLOR diffuse;
17734 quad[] =
17736 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
17737 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
17738 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
17739 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
17741 static const struct
17743 struct vec4 position;
17744 D3DCOLOR diffuse;
17746 tquad[] =
17748 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
17749 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
17750 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
17751 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
17753 unsigned int i;
17754 static const D3DMATRIX zero =
17756 1.0f, 0.0f, 0.0f, 0.0f,
17757 0.0f, 1.0f, 0.0f, 0.0f,
17758 0.0f, 0.0f, 0.0f, 0.0f,
17759 0.0f, 0.0f, 0.0f, 1.0f
17760 }}};
17761 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
17762 * have an effect on RHW draws. */
17763 static const D3DMATRIX identity =
17765 1.0f, 0.0f, 0.0f, 0.0f,
17766 0.0f, 1.0f, 0.0f, 0.0f,
17767 0.0f, 0.0f, 1.0f, 0.0f,
17768 0.0f, 0.0f, 0.0f, 1.0f
17769 }}};
17770 static const struct
17772 DWORD pos_type;
17773 const void *quad;
17774 size_t stride;
17775 const D3DMATRIX *matrix;
17776 union
17778 float f;
17779 DWORD d;
17780 } start, end;
17781 D3DFOGMODE vfog, tfog;
17782 DWORD color, color_broken, color_broken2;
17784 tests[] =
17786 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
17788 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
17789 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
17790 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
17791 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
17792 * parameters to 0.0 and 1.0 in the table fog case. */
17793 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
17794 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
17795 /* test_fog_interpolation shows that vertex fog evaluates the fog
17796 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
17797 * that the abs happens before the fog equation is evaluated.
17799 * Vertex fog abs() behavior is the same on all GPUs. */
17800 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
17801 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
17802 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
17803 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
17804 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
17805 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
17807 D3DCAPS9 caps;
17809 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17810 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17811 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17812 ok(!!d3d, "Failed to create a D3D object.\n");
17814 if (!(device = create_device(d3d, window, window, TRUE)))
17816 skip("Failed to create a D3D device, skipping tests.\n");
17817 IDirect3D9_Release(d3d);
17818 DestroyWindow(window);
17819 return;
17822 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17823 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17824 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17825 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
17827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17828 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17830 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17832 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17834 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
17836 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
17838 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17840 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
17841 continue;
17843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
17844 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17846 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
17847 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17848 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
17849 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
17851 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
17853 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
17855 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
17857 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17859 hr = IDirect3DDevice9_BeginScene(device);
17860 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17861 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
17862 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17863 hr = IDirect3DDevice9_EndScene(device);
17864 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17866 color = getPixelColor(device, 320, 240);
17867 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
17868 || broken(color_match(color, tests[i].color_broken2, 2)),
17869 "Got unexpected color 0x%08x, case %u.\n", color, i);
17870 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17871 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17874 refcount = IDirect3DDevice9_Release(device);
17875 ok(!refcount, "Device has %u references left.\n", refcount);
17876 IDirect3D9_Release(d3d);
17877 DestroyWindow(window);
17880 static void test_position_index(void)
17882 static const D3DVERTEXELEMENT9 decl_elements[] =
17884 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
17885 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
17886 D3DDECL_END()
17888 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
17889 * but works on Nvidia.
17890 * MSDN is not consistent on this point. */
17891 static const DWORD vs_code[] =
17893 0xfffe0300, /* vs_3_0 */
17894 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17895 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
17896 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
17897 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
17898 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
17899 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
17900 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
17901 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
17902 0x0000ffff /* end */
17904 static const DWORD vs_code_2[] =
17906 0xfffe0300, /* vs_3_0 */
17907 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17908 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
17909 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
17910 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
17911 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
17912 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
17913 0x0000ffff /* end */
17915 static const DWORD ps_code[] =
17917 0xffff0300, /* ps_3_0 */
17918 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
17919 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
17920 0x0000ffff /* end */
17922 static const DWORD ps_code_2[] =
17924 0xffff0300, /* ps_3_0 */
17925 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
17926 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
17927 0x0000ffff /* end */
17929 /* This one is considered invalid by the native shader assembler. */
17930 static const DWORD ps_code_bad[] =
17932 0xffff0300, /* ps_3_0 */
17933 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17934 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
17935 0x0000ffff /* end */
17937 static const struct
17939 struct vec3 position;
17940 struct vec3 position1;
17942 quad[] =
17944 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
17945 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
17946 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
17947 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
17949 static const struct
17951 struct vec2 position;
17952 D3DCOLOR expected_color;
17953 D3DCOLOR broken_color;
17955 expected_colors[] =
17957 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
17958 {{240, 240}, 0x009f6000, 0x00ff00ff},
17959 {{400, 240}, 0x00609f00, 0x00ff00ff},
17960 {{560, 240}, 0x0020df00, 0x00ff00ff},
17962 IDirect3D9 *d3d;
17963 IDirect3DDevice9 *device;
17964 IDirect3DVertexDeclaration9 *vertex_declaration;
17965 IDirect3DVertexShader9 *vs, *vs2;
17966 IDirect3DPixelShader9 *ps, *ps2;
17967 D3DCAPS9 caps;
17968 D3DCOLOR color;
17969 ULONG refcount;
17970 HWND window;
17971 HRESULT hr;
17972 unsigned int i;
17974 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17975 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17976 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17977 ok(!!d3d, "Failed to create a D3D object.\n");
17978 if (!(device = create_device(d3d, window, window, TRUE)))
17980 skip("Failed to create a D3D device, skipping tests.\n");
17981 goto done;
17984 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17985 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17986 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
17987 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
17989 skip("Shader model 3.0 unsupported, skipping tests.\n");
17990 IDirect3DDevice9_Release(device);
17991 goto done;
17994 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
17995 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
17997 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
17998 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18000 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18001 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18002 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18003 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18005 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18006 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18008 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18009 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18011 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18012 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18013 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18014 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18016 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18017 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18020 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18021 hr = IDirect3DDevice9_BeginScene(device);
18022 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18024 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18025 hr = IDirect3DDevice9_EndScene(device);
18026 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18028 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18030 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18031 ok (color_match(color, expected_colors[i].expected_color, 1)
18032 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18033 "Got unexpected color 0x%08x, case %u.\n", color, i);
18036 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18037 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18040 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18041 hr = IDirect3DDevice9_BeginScene(device);
18042 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18043 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18044 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18045 hr = IDirect3DDevice9_EndScene(device);
18046 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18048 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18050 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18051 ok (color_match(color, expected_colors[i].expected_color, 1)
18052 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18053 "Got unexpected color 0x%08x, case %u.\n", color, i);
18056 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18057 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18060 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18061 hr = IDirect3DDevice9_BeginScene(device);
18062 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18064 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18065 hr = IDirect3DDevice9_EndScene(device);
18066 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18068 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18070 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18071 ok (color_match(color, expected_colors[i].expected_color, 1),
18072 "Got unexpected color 0x%08x, case %u.\n", color, i);
18075 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18076 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18078 IDirect3DPixelShader9_Release(ps2);
18079 IDirect3DPixelShader9_Release(ps);
18080 IDirect3DVertexShader9_Release(vs2);
18081 IDirect3DVertexShader9_Release(vs);
18082 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18083 refcount = IDirect3DDevice9_Release(device);
18084 ok(!refcount, "Device has %u references left.\n", refcount);
18086 done:
18087 IDirect3D9_Release(d3d);
18088 DestroyWindow(window);
18091 static void test_table_fog_zw(void)
18093 HRESULT hr;
18094 IDirect3DDevice9 *device;
18095 IDirect3D9 *d3d;
18096 ULONG refcount;
18097 HWND window;
18098 D3DCOLOR color;
18099 D3DCAPS9 caps;
18100 static struct
18102 struct vec4 position;
18103 D3DCOLOR diffuse;
18105 quad[] =
18107 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18108 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18109 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18110 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18112 static const D3DMATRIX identity =
18114 1.0f, 0.0f, 0.0f, 0.0f,
18115 0.0f, 1.0f, 0.0f, 0.0f,
18116 0.0f, 0.0f, 1.0f, 0.0f,
18117 0.0f, 0.0f, 0.0f, 1.0f
18118 }}};
18119 static const struct
18121 float z, w;
18122 D3DZBUFFERTYPE z_test;
18123 D3DCOLOR color;
18125 tests[] =
18127 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18128 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18129 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18130 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18131 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18132 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18133 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18134 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18136 unsigned int i;
18138 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18139 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18140 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18141 ok(!!d3d, "Failed to create a D3D object.\n");
18143 if (!(device = create_device(d3d, window, window, TRUE)))
18145 skip("Failed to create a D3D device, skipping tests.\n");
18146 IDirect3D9_Release(d3d);
18147 DestroyWindow(window);
18148 return;
18151 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18152 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18153 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18155 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18156 goto done;
18159 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18160 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18162 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18164 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18166 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18167 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18168 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18169 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18171 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18172 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18173 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18175 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18178 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18180 quad[0].position.z = tests[i].z;
18181 quad[1].position.z = tests[i].z;
18182 quad[2].position.z = tests[i].z;
18183 quad[3].position.z = tests[i].z;
18184 quad[0].position.w = tests[i].w;
18185 quad[1].position.w = tests[i].w;
18186 quad[2].position.w = tests[i].w;
18187 quad[3].position.w = tests[i].w;
18188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18189 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18191 hr = IDirect3DDevice9_BeginScene(device);
18192 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18195 hr = IDirect3DDevice9_EndScene(device);
18196 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18198 color = getPixelColor(device, 320, 240);
18199 ok(color_match(color, tests[i].color, 2),
18200 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18201 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18202 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18205 done:
18206 refcount = IDirect3DDevice9_Release(device);
18207 ok(!refcount, "Device has %u references left.\n", refcount);
18208 IDirect3D9_Release(d3d);
18209 DestroyWindow(window);
18212 static void test_signed_formats(void)
18214 IDirect3DDevice9 *device;
18215 HWND window;
18216 HRESULT hr;
18217 unsigned int i, j, x, y;
18218 IDirect3DTexture9 *texture, *texture_sysmem;
18219 IDirect3DSurface9 *src_surface, *dst_surface;
18220 D3DLOCKED_RECT locked_rect;
18221 IDirect3DPixelShader9 *shader, *shader_alpha;
18222 IDirect3D9 *d3d;
18223 D3DCOLOR color;
18224 D3DCAPS9 caps;
18225 ULONG refcount;
18227 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18228 * to the other formats because L6V5U5 is the lowest precision format.
18229 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18230 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18231 * Some other intermediate values are tested too. The input value -15
18232 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18233 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18234 * using the expected output data the 8 bit and 16 bit values in V8U8
18235 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18236 * -1, 1 and -127 are not tested in V8U8.
18238 * 8 bit specific values like -127 are tested in the Q channel of
18239 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18240 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18241 * -128. The difference between using -127 or -128 as the lowest
18242 * possible value gets lost in the slop of 1 though. */
18243 static const USHORT content_v8u8[4][4] =
18245 {0x0000, 0x7f7f, 0x8880, 0x0000},
18246 {0x0080, 0x8000, 0x7f00, 0x007f},
18247 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18248 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18250 static const DWORD content_v16u16[4][4] =
18252 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18253 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18254 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18255 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18257 static const DWORD content_q8w8v8u8[4][4] =
18259 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18260 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18261 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18262 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18264 static const DWORD content_x8l8v8u8[4][4] =
18266 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18267 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18268 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18269 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18271 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18272 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18273 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18274 * though.
18276 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18277 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18278 * the proper results of -6 and -2.
18280 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18281 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18282 * is 0x84 instead of 0x80. */
18283 static const USHORT content_l6v5u5[4][4] =
18285 {0x0000, 0xfdef, 0x0230, 0xfc00},
18286 {0x0010, 0x0200, 0x01e0, 0x000f},
18287 {0x4067, 0x53b9, 0x0421, 0xffff},
18288 {0x8108, 0x0318, 0xc28c, 0x909c},
18290 static const struct
18292 D3DFORMAT format;
18293 const char *name;
18294 const void *content;
18295 SIZE_T pixel_size;
18296 BOOL blue, alpha;
18297 unsigned int slop, slop_broken, alpha_broken;
18299 formats[] =
18301 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18302 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18303 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18304 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18305 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18307 static const struct
18309 D3DPOOL pool;
18310 UINT width;
18311 RECT src_rect;
18312 POINT dst_point;
18314 tests[] =
18316 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18317 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18318 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18319 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18321 static const DWORD shader_code[] =
18323 0xffff0101, /* ps_1_1 */
18324 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18325 0x00000042, 0xb00f0000, /* tex t0 */
18326 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18327 0x0000ffff /* end */
18329 static const DWORD shader_code_alpha[] =
18331 /* The idea of this shader is to replicate the alpha value in .rg, and set
18332 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18333 0xffff0101, /* ps_1_1 */
18334 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18335 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18336 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18337 0x00000042, 0xb00f0000, /* tex t0 */
18338 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18339 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18340 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18341 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18342 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18343 0x0000ffff /* end */
18345 static const struct
18347 struct vec3 position;
18348 struct vec2 texcrd;
18350 quad[] =
18352 /* Flip the y coordinate to make the input and
18353 * output arrays easier to compare. */
18354 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18355 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18356 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18357 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18359 static const D3DCOLOR expected_alpha[4][4] =
18361 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18362 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18363 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18364 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18366 static const BOOL alpha_broken[4][4] =
18368 {FALSE, FALSE, FALSE, FALSE},
18369 {FALSE, FALSE, FALSE, FALSE},
18370 {FALSE, FALSE, FALSE, TRUE },
18371 {FALSE, FALSE, FALSE, FALSE},
18373 static const D3DCOLOR expected_colors[4][4] =
18375 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18376 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18377 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18378 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18380 static const D3DCOLOR expected_colors2[4][4] =
18382 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18383 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18384 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18385 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18387 static const D3DCOLOR expected_colors3[4] =
18389 0x00018080,
18390 0x00ba98a0,
18391 0x00ba98a0,
18392 0x00c3c3c0,
18394 D3DCOLOR expected_color;
18396 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18397 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18398 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18399 ok(!!d3d, "Failed to create a D3D object.\n");
18401 if (!(device = create_device(d3d, window, window, TRUE)))
18403 skip("Failed to create a D3D device, skipping tests.\n");
18404 IDirect3D9_Release(d3d);
18405 DestroyWindow(window);
18406 return;
18409 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18410 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18412 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18414 skip("Pixel shaders not supported, skipping converted format test.\n");
18415 goto done;
18418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18419 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18421 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18422 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18423 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18424 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18425 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18427 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18429 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18430 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18431 if (FAILED(hr))
18433 skip("Format %s not supported, skipping.\n", formats[i].name);
18434 continue;
18437 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18439 texture_sysmem = NULL;
18440 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18441 formats[i].format, tests[j].pool, &texture, NULL);
18442 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18444 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18445 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18446 for (y = 0; y < 4; y++)
18448 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18449 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18450 tests[j].width * formats[i].pixel_size);
18452 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18453 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18455 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18457 texture_sysmem = texture;
18458 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18459 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18460 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18462 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18463 (IDirect3DBaseTexture9 *)texture);
18464 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18467 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18468 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18469 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18470 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18473 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18474 hr = IDirect3DDevice9_BeginScene(device);
18475 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18477 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18478 hr = IDirect3DDevice9_EndScene(device);
18479 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18481 for (y = 0; y < 4; y++)
18483 for (x = 0; x < tests[j].width; x++)
18485 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18486 if (formats[i].alpha)
18487 expected_color = expected_alpha[y][x];
18488 else
18489 expected_color = 0x00ffff00;
18491 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18492 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18493 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18494 expected_color, color, formats[i].name, x, y);
18497 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18498 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18500 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18501 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18504 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18505 hr = IDirect3DDevice9_BeginScene(device);
18506 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18507 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18508 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18509 hr = IDirect3DDevice9_EndScene(device);
18510 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18512 for (y = 0; y < 4; y++)
18514 for (x = 0; x < tests[j].width; x++)
18516 expected_color = expected_colors[y][x];
18517 if (!formats[i].blue)
18518 expected_color |= 0x000000ff;
18520 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18521 ok(color_match(color, expected_color, formats[i].slop)
18522 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18523 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18524 expected_color, color, formats[i].name, x, y);
18527 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18528 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18530 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18532 IDirect3DTexture9_Release(texture);
18533 continue;
18536 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18537 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18538 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18539 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18541 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18542 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18543 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18545 IDirect3DSurface9_Release(dst_surface);
18546 IDirect3DSurface9_Release(src_surface);
18548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18549 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18550 hr = IDirect3DDevice9_BeginScene(device);
18551 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18553 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18554 hr = IDirect3DDevice9_EndScene(device);
18555 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18557 for (y = 0; y < 4; y++)
18559 for (x = 0; x < tests[j].width; x++)
18561 if (tests[j].width == 4)
18562 expected_color = expected_colors2[y][x];
18563 else
18564 expected_color = expected_colors3[y];
18566 if (!formats[i].blue)
18567 expected_color |= 0x000000ff;
18569 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18570 ok(color_match(color, expected_color, formats[i].slop)
18571 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18572 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18573 expected_color, color, formats[i].name, x, y);
18576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18577 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18579 IDirect3DTexture9_Release(texture_sysmem);
18580 IDirect3DTexture9_Release(texture);
18584 IDirect3DPixelShader9_Release(shader);
18585 IDirect3DPixelShader9_Release(shader_alpha);
18587 done:
18588 refcount = IDirect3DDevice9_Release(device);
18589 ok(!refcount, "Device has %u references left.\n", refcount);
18590 IDirect3D9_Release(d3d);
18591 DestroyWindow(window);
18594 static void test_multisample_mismatch(void)
18596 IDirect3DDevice9 *device;
18597 IDirect3D9 *d3d;
18598 HWND window;
18599 HRESULT hr;
18600 D3DCOLOR color;
18601 ULONG refcount;
18602 IDirect3DSurface9 *rt, *rt_multi, *ds;
18603 static const struct
18605 struct vec3 position;
18606 DWORD color;
18608 quad[] =
18610 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
18611 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
18612 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
18613 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
18616 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18617 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18618 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18619 ok(!!d3d, "Failed to create a D3D object.\n");
18620 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18621 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18623 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
18624 IDirect3D9_Release(d3d);
18625 return;
18627 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18628 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18630 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
18631 IDirect3D9_Release(d3d);
18632 return;
18635 if (!(device = create_device(d3d, window, window, TRUE)))
18637 skip("Failed to create a D3D device, skipping tests.\n");
18638 IDirect3D9_Release(d3d);
18639 DestroyWindow(window);
18640 return;
18643 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18644 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
18645 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
18647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
18648 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18650 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18651 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
18652 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
18653 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
18654 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18655 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18658 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18660 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18662 /* Clear with incompatible buffers. Partial and combined clears. */
18663 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18664 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
18666 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18667 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
18668 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18670 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
18671 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18672 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18673 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18674 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18675 color = getPixelColor(device, 320, 240);
18676 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18678 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18680 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
18681 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
18682 * the Z only clear case nor in the combined clear case. */
18683 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18684 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18685 hr = IDirect3DDevice9_BeginScene(device);
18686 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18688 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18689 hr = IDirect3DDevice9_EndScene(device);
18690 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18691 color = getPixelColor(device, 62, 240);
18692 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18693 color = getPixelColor(device, 64, 240);
18694 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18695 "Got unexpected color 0x%08x.\n", color);
18696 color = getPixelColor(device, 318, 240);
18697 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18698 "Got unexpected color 0x%08x.\n", color);
18699 color = getPixelColor(device, 322, 240);
18700 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18701 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18702 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18704 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
18705 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
18706 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
18707 * show up either. Only test the ZENABLE = FALSE case for now. */
18708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18709 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18710 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18711 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18713 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18714 hr = IDirect3DDevice9_BeginScene(device);
18715 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18717 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18718 hr = IDirect3DDevice9_EndScene(device);
18719 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18721 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18722 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18723 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18724 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18725 color = getPixelColor(device, 320, 240);
18726 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18727 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18728 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18730 IDirect3DSurface9_Release(ds);
18732 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
18733 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
18734 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
18735 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
18736 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
18737 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18738 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
18739 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18740 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
18742 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18744 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18745 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18746 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18747 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18748 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
18749 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18750 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
18751 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18753 color = getPixelColor(device, 320, 240);
18754 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18755 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18756 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18758 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18759 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18760 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18761 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18762 hr = IDirect3DDevice9_BeginScene(device);
18763 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18764 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18765 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18766 hr = IDirect3DDevice9_EndScene(device);
18767 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18769 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18770 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18771 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18772 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18773 color = getPixelColor(device, 62, 240);
18774 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18775 color = getPixelColor(device, 318, 240);
18776 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18777 "Got unexpected color 0x%08x.\n", color);
18778 color = getPixelColor(device, 322, 240);
18779 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
18780 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18781 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18783 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
18784 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
18785 * is disabled. Again only test the ZENABLE = FALSE case. */
18786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18787 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18789 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18790 hr = IDirect3DDevice9_BeginScene(device);
18791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18793 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18794 hr = IDirect3DDevice9_EndScene(device);
18795 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18796 color = getPixelColor(device, 320, 240);
18797 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18798 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18799 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18801 IDirect3DSurface9_Release(rt);
18802 IDirect3DSurface9_Release(ds);
18803 IDirect3DSurface9_Release(rt_multi);
18805 refcount = IDirect3DDevice9_Release(device);
18806 ok(!refcount, "Device has %u references left.\n", refcount);
18807 IDirect3D9_Release(d3d);
18808 DestroyWindow(window);
18811 static void test_texcoordindex(void)
18813 static const D3DMATRIX mat =
18815 1.0f, 0.0f, 0.0f, 0.0f,
18816 0.0f, 0.0f, 0.0f, 0.0f,
18817 0.0f, 0.0f, 0.0f, 0.0f,
18818 0.0f, 0.0f, 0.0f, 0.0f,
18819 }}};
18820 static const struct
18822 struct vec3 pos;
18823 struct vec2 texcoord1;
18824 struct vec2 texcoord2;
18825 struct vec2 texcoord3;
18827 quad[] =
18829 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
18830 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
18831 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
18832 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
18834 IDirect3DDevice9 *device;
18835 IDirect3D9 *d3d9;
18836 HWND window;
18837 HRESULT hr;
18838 IDirect3DTexture9 *texture1, *texture2;
18839 D3DLOCKED_RECT locked_rect;
18840 ULONG refcount;
18841 D3DCOLOR color;
18842 DWORD *ptr;
18844 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18845 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18846 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
18847 ok(!!d3d9, "Failed to create a D3D object.\n");
18848 if (!(device = create_device(d3d9, window, window, TRUE)))
18850 skip("Failed to create a D3D device, skipping tests.\n");
18851 IDirect3D9_Release(d3d9);
18852 DestroyWindow(window);
18853 return;
18856 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
18857 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18858 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
18859 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18861 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
18862 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18863 ptr = locked_rect.pBits;
18864 ptr[0] = 0xff000000;
18865 ptr[1] = 0xff00ff00;
18866 ptr[2] = 0xff0000ff;
18867 ptr[3] = 0xff00ffff;
18868 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
18869 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18871 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
18872 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18873 ptr = locked_rect.pBits;
18874 ptr[0] = 0xff000000;
18875 ptr[1] = 0xff0000ff;
18876 ptr[2] = 0xffff0000;
18877 ptr[3] = 0xffff00ff;
18878 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
18879 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18881 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
18882 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18883 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
18884 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
18886 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18887 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18888 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
18889 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18890 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18891 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18892 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18893 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
18894 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18895 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18896 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18897 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
18898 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18899 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
18900 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
18903 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
18904 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
18905 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
18907 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
18908 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18910 hr = IDirect3DDevice9_BeginScene(device);
18911 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18913 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18914 hr = IDirect3DDevice9_EndScene(device);
18915 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18917 color = getPixelColor(device, 160, 120);
18918 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
18919 color = getPixelColor(device, 480, 120);
18920 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
18921 color = getPixelColor(device, 160, 360);
18922 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
18923 color = getPixelColor(device, 480, 360);
18924 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
18926 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
18927 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
18928 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
18929 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
18931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
18932 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18934 hr = IDirect3DDevice9_BeginScene(device);
18935 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18937 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18938 hr = IDirect3DDevice9_EndScene(device);
18939 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18941 color = getPixelColor(device, 160, 120);
18942 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
18943 color = getPixelColor(device, 480, 120);
18944 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
18945 color = getPixelColor(device, 160, 360);
18946 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
18947 color = getPixelColor(device, 480, 360);
18948 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
18950 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
18951 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
18952 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
18953 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
18955 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
18956 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18958 hr = IDirect3DDevice9_BeginScene(device);
18959 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18961 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18962 hr = IDirect3DDevice9_EndScene(device);
18963 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18965 color = getPixelColor(device, 160, 120);
18966 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
18967 color = getPixelColor(device, 480, 120);
18968 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
18969 color = getPixelColor(device, 160, 360);
18970 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
18971 color = getPixelColor(device, 480, 360);
18972 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
18974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18975 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18977 IDirect3DTexture9_Release(texture1);
18978 IDirect3DTexture9_Release(texture2);
18980 refcount = IDirect3DDevice9_Release(device);
18981 ok(!refcount, "Device has %u references left.\n", refcount);
18982 IDirect3D9_Release(d3d9);
18983 DestroyWindow(window);
18986 START_TEST(visual)
18988 D3DADAPTER_IDENTIFIER9 identifier;
18989 IDirect3D9 *d3d;
18990 HRESULT hr;
18992 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
18994 skip("could not create D3D9 object\n");
18995 return;
18998 memset(&identifier, 0, sizeof(identifier));
18999 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
19000 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
19001 trace("Driver string: \"%s\"\n", identifier.Driver);
19002 trace("Description string: \"%s\"\n", identifier.Description);
19003 /* Only Windows XP's default VGA driver should have an empty description */
19004 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
19005 trace("Device name string: \"%s\"\n", identifier.DeviceName);
19006 ok(identifier.DeviceName[0], "Empty device name.\n");
19007 trace("Driver version %d.%d.%d.%d\n",
19008 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
19009 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
19011 IDirect3D9_Release(d3d);
19013 test_sanity();
19014 depth_clamp_test();
19015 stretchrect_test();
19016 lighting_test();
19017 test_specular_lighting();
19018 clear_test();
19019 color_fill_test();
19020 fog_test();
19021 test_cube_wrap();
19022 z_range_test();
19023 maxmip_test();
19024 offscreen_test();
19025 ds_size_test();
19026 test_blend();
19027 shademode_test();
19028 srgbtexture_test();
19029 release_buffer_test();
19030 float_texture_test();
19031 g16r16_texture_test();
19032 pixelshader_blending_test();
19033 texture_transform_flags_test();
19034 autogen_mipmap_test();
19035 fixed_function_decl_test();
19036 conditional_np2_repeat_test();
19037 fixed_function_bumpmap_test();
19038 pointsize_test();
19039 tssargtemp_test();
19040 np2_stretch_rect_test();
19041 yuv_color_test();
19042 yuv_layout_test();
19043 zwriteenable_test();
19044 alphatest_test();
19045 viewport_test();
19046 test_constant_clamp_vs();
19047 test_compare_instructions();
19048 test_mova();
19049 loop_index_test();
19050 sincos_test();
19051 sgn_test();
19052 clip_planes_test();
19053 test_vshader_input();
19054 test_vshader_float16();
19055 stream_test();
19056 fog_with_shader_test();
19057 texbem_test();
19058 texdepth_test();
19059 texkill_test();
19060 volume_v16u16_test();
19061 constant_clamp_ps_test();
19062 cnd_test();
19063 dp2add_ps_test();
19064 unbound_sampler_test();
19065 nested_loop_test();
19066 pretransformed_varying_test();
19067 vface_register_test();
19068 test_fragment_coords();
19069 multiple_rendertargets_test();
19070 texop_test();
19071 texop_range_test();
19072 alphareplicate_test();
19073 dp3_alpha_test();
19074 depth_buffer_test();
19075 depth_buffer2_test();
19076 depth_blit_test();
19077 intz_test();
19078 shadow_test();
19079 fp_special_test();
19080 depth_bounds_test();
19081 srgbwrite_format_test();
19082 update_surface_test();
19083 multisample_get_rtdata_test();
19084 zenable_test();
19085 fog_special_test();
19086 volume_srgb_test();
19087 volume_dxt5_test();
19088 add_dirty_rect_test();
19089 multisampled_depth_buffer_test();
19090 resz_test();
19091 stencil_cull_test();
19092 test_per_stage_constant();
19093 test_3dc_formats();
19094 test_fog_interpolation();
19095 test_negative_fixedfunction_fog();
19096 test_position_index();
19097 test_table_fog_zw();
19098 test_signed_formats();
19099 test_multisample_mismatch();
19100 test_texcoordindex();