d3d9/tests: Fix caps check in texdepth_test().
[wine.git] / dlls / d3d9 / tests / visual.c
blobdf29221c8421ca32a84d0c84ca9ea8d5f3637db3
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, 4))
5336 skip("No ps_1_4 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_nocolor, *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_nocolor[] = {
8411 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8412 D3DDECL_END()
8414 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8415 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8416 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8417 D3DDECL_END()
8419 static const struct
8421 struct vec3 position;
8422 DWORD diffuse;
8424 quad1[] = /* D3DCOLOR */
8426 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8427 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8428 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8429 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8431 quad2[] = /* UBYTE4N */
8433 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8434 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8435 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8436 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8438 static const struct
8440 struct vec3 position;
8441 struct { unsigned short x, y, z, w; } color;
8443 quad3[] = /* USHORT4N */
8445 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8446 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8447 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8448 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8450 static const struct
8452 struct vec3 position;
8453 struct vec4 color;
8455 quad4[] =
8457 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8458 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8459 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8460 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8462 static const DWORD colors[] =
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,
8476 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8477 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8478 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8479 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8481 static const float quads[] =
8483 -1.0f, -1.0f, 0.1f,
8484 -1.0f, 0.0f, 0.1f,
8485 0.0f, -1.0f, 0.1f,
8486 0.0f, 0.0f, 0.1f,
8488 0.0f, -1.0f, 0.1f,
8489 0.0f, 0.0f, 0.1f,
8490 1.0f, -1.0f, 0.1f,
8491 1.0f, 0.0f, 0.1f,
8493 0.0f, 0.0f, 0.1f,
8494 0.0f, 1.0f, 0.1f,
8495 1.0f, 0.0f, 0.1f,
8496 1.0f, 1.0f, 0.1f,
8498 -1.0f, 0.0f, 0.1f,
8499 -1.0f, 1.0f, 0.1f,
8500 0.0f, 0.0f, 0.1f,
8501 0.0f, 1.0f, 0.1f,
8503 static const struct
8505 struct vec4 position;
8506 DWORD diffuse;
8508 quad_transformed[] =
8510 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8511 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8512 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8513 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8516 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8517 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8518 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8519 ok(!!d3d, "Failed to create a D3D object.\n");
8520 if (!(device = create_device(d3d, window, window, TRUE)))
8522 skip("Failed to create a D3D device, skipping tests.\n");
8523 goto done;
8526 memset(&caps, 0, sizeof(caps));
8527 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8528 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8530 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8531 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8533 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8534 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8535 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8536 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8537 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8538 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8539 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8540 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8541 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8542 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8543 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8544 } else {
8545 trace("D3DDTCAPS_UBYTE4N not supported\n");
8546 dcl_ubyte_2 = NULL;
8547 dcl_ubyte = NULL;
8549 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8550 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8551 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8552 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8553 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8554 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8556 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8557 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8558 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8559 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8562 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8564 hr = IDirect3DDevice9_BeginScene(device);
8565 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8567 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8568 if (dcl_color)
8570 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8571 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8573 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8576 /* Tests with non-standard fixed function types fail on the refrast. The
8577 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8578 * All those differences even though we're using software vertex
8579 * processing. Doh! */
8580 if (dcl_ubyte)
8582 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8583 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8585 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8586 ub_ok = SUCCEEDED(hr);
8589 if (dcl_short)
8591 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8592 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8594 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8595 s_ok = SUCCEEDED(hr);
8598 if (dcl_float)
8600 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8601 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8603 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8604 f_ok = SUCCEEDED(hr);
8607 hr = IDirect3DDevice9_EndScene(device);
8608 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8610 if(dcl_short) {
8611 color = getPixelColor(device, 480, 360);
8612 ok(color == 0x000000ff || !s_ok,
8613 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8615 if(dcl_ubyte) {
8616 color = getPixelColor(device, 160, 120);
8617 ok(color == 0x0000ffff || !ub_ok,
8618 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8620 if(dcl_color) {
8621 color = getPixelColor(device, 160, 360);
8622 ok(color == 0x00ffff00,
8623 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8625 if(dcl_float) {
8626 color = getPixelColor(device, 480, 120);
8627 ok(color == 0x00ff0000 || !f_ok,
8628 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8630 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8632 /* The following test with vertex buffers doesn't serve to find out new
8633 * information from windows. It is a plain regression test because wined3d
8634 * uses different codepaths for attribute conversion with vertex buffers.
8635 * It makes sure that the vertex buffer one works, while the above tests
8636 * whether the immediate mode code works. */
8637 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8639 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8640 hr = IDirect3DDevice9_BeginScene(device);
8641 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8643 if (dcl_color)
8645 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8646 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8647 memcpy(data, quad1, sizeof(quad1));
8648 hr = IDirect3DVertexBuffer9_Unlock(vb);
8649 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8650 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8651 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8652 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8653 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8654 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8655 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8658 if (dcl_ubyte)
8660 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8661 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8662 memcpy(data, quad2, sizeof(quad2));
8663 hr = IDirect3DVertexBuffer9_Unlock(vb);
8664 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8665 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8666 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8667 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8668 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8669 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8670 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8671 ub_ok = SUCCEEDED(hr);
8674 if (dcl_short)
8676 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8677 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8678 memcpy(data, quad3, sizeof(quad3));
8679 hr = IDirect3DVertexBuffer9_Unlock(vb);
8680 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8681 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8682 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8683 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8684 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8685 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8686 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8687 s_ok = SUCCEEDED(hr);
8690 if (dcl_float)
8692 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8693 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8694 memcpy(data, quad4, sizeof(quad4));
8695 hr = IDirect3DVertexBuffer9_Unlock(vb);
8696 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8697 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8698 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8699 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8700 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8701 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8702 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8703 f_ok = SUCCEEDED(hr);
8706 hr = IDirect3DDevice9_EndScene(device);
8707 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8709 if(dcl_short) {
8710 color = getPixelColor(device, 480, 360);
8711 ok(color == 0x000000ff || !s_ok,
8712 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8714 if(dcl_ubyte) {
8715 color = getPixelColor(device, 160, 120);
8716 ok(color == 0x0000ffff || !ub_ok,
8717 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8719 if(dcl_color) {
8720 color = getPixelColor(device, 160, 360);
8721 ok(color == 0x00ffff00,
8722 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8724 if(dcl_float) {
8725 color = getPixelColor(device, 480, 120);
8726 ok(color == 0x00ff0000 || !f_ok,
8727 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8729 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8731 /* Test with no diffuse color attribute. */
8732 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8733 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8735 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
8736 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8737 hr = IDirect3DDevice9_BeginScene(device);
8738 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
8740 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8741 hr = IDirect3DDevice9_EndScene(device);
8742 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8744 color = getPixelColor(device, 160, 360);
8745 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
8747 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8749 /* Test what happens with specular lighting enabled and no specular color attribute. */
8750 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8751 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8752 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8753 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
8754 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
8755 hr = IDirect3DDevice9_BeginScene(device);
8756 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8758 if (dcl_color)
8760 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8761 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8763 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8765 if (dcl_ubyte)
8767 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8768 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8770 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8771 ub_ok = SUCCEEDED(hr);
8773 if (dcl_short)
8775 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8776 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8778 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8779 s_ok = SUCCEEDED(hr);
8781 if (dcl_float)
8783 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8784 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8786 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8787 f_ok = SUCCEEDED(hr);
8790 hr = IDirect3DDevice9_EndScene(device);
8791 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
8793 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
8795 if (dcl_short)
8797 color = getPixelColor(device, 480, 360);
8798 ok(color == 0x000000ff || !s_ok,
8799 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
8801 if (dcl_ubyte)
8803 color = getPixelColor(device, 160, 120);
8804 ok(color == 0x0000ffff || !ub_ok,
8805 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
8807 if (dcl_color)
8809 color = getPixelColor(device, 160, 360);
8810 ok(color == 0x00ffff00,
8811 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
8813 if (dcl_float)
8815 color = getPixelColor(device, 480, 120);
8816 ok(color == 0x00ff0000 || !f_ok,
8817 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
8819 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8821 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
8822 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8823 memcpy(data, quad_transformed, sizeof(quad_transformed));
8824 hr = IDirect3DVertexBuffer9_Unlock(vb);
8825 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8827 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
8828 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8830 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8831 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8833 hr = IDirect3DDevice9_BeginScene(device);
8834 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8835 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
8836 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8837 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8838 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8839 hr = IDirect3DDevice9_EndScene(device);
8840 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8842 color = getPixelColor(device, 88, 108);
8843 ok(color == 0x000000ff,
8844 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8845 color = getPixelColor(device, 92, 108);
8846 ok(color == 0x000000ff,
8847 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8848 color = getPixelColor(device, 88, 112);
8849 ok(color == 0x000000ff,
8850 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8851 color = getPixelColor(device, 92, 112);
8852 ok(color == 0x00ffff00,
8853 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8855 color = getPixelColor(device, 568, 108);
8856 ok(color == 0x000000ff,
8857 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8858 color = getPixelColor(device, 572, 108);
8859 ok(color == 0x000000ff,
8860 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8861 color = getPixelColor(device, 568, 112);
8862 ok(color == 0x00ffff00,
8863 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8864 color = getPixelColor(device, 572, 112);
8865 ok(color == 0x000000ff,
8866 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8868 color = getPixelColor(device, 88, 298);
8869 ok(color == 0x000000ff,
8870 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8871 color = getPixelColor(device, 92, 298);
8872 ok(color == 0x00ffff00,
8873 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8874 color = getPixelColor(device, 88, 302);
8875 ok(color == 0x000000ff,
8876 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8877 color = getPixelColor(device, 92, 302);
8878 ok(color == 0x000000ff,
8879 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8881 color = getPixelColor(device, 568, 298);
8882 ok(color == 0x00ffff00,
8883 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8884 color = getPixelColor(device, 572, 298);
8885 ok(color == 0x000000ff,
8886 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8887 color = getPixelColor(device, 568, 302);
8888 ok(color == 0x000000ff,
8889 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8890 color = getPixelColor(device, 572, 302);
8891 ok(color == 0x000000ff,
8892 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8894 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8896 /* This test is pointless without those two declarations: */
8897 if((!dcl_color_2) || (!dcl_ubyte_2)) {
8898 skip("color-ubyte switching test declarations aren't supported\n");
8899 goto out;
8902 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
8903 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8904 memcpy(data, quads, sizeof(quads));
8905 hr = IDirect3DVertexBuffer9_Unlock(vb);
8906 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8907 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
8908 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8909 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8910 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
8911 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8912 memcpy(data, colors, sizeof(colors));
8913 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8914 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8916 for(i = 0; i < 2; i++) {
8917 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8920 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
8921 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8922 if(i == 0) {
8923 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
8924 } else {
8925 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
8927 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8929 hr = IDirect3DDevice9_BeginScene(device);
8930 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8932 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8933 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8934 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8935 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8936 ub_ok = SUCCEEDED(hr);
8938 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
8939 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8940 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8941 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8943 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8944 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8945 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8946 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8947 ub_ok = (SUCCEEDED(hr) && ub_ok);
8949 hr = IDirect3DDevice9_EndScene(device);
8950 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8952 if(i == 0) {
8953 color = getPixelColor(device, 480, 360);
8954 ok(color == 0x00ff0000,
8955 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
8956 color = getPixelColor(device, 160, 120);
8957 ok(color == 0x00ffffff,
8958 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8959 color = getPixelColor(device, 160, 360);
8960 ok(color == 0x000000ff || !ub_ok,
8961 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8962 color = getPixelColor(device, 480, 120);
8963 ok(color == 0x000000ff || !ub_ok,
8964 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8965 } else {
8966 color = getPixelColor(device, 480, 360);
8967 ok(color == 0x000000ff,
8968 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
8969 color = getPixelColor(device, 160, 120);
8970 ok(color == 0x00ffffff,
8971 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8972 color = getPixelColor(device, 160, 360);
8973 ok(color == 0x00ff0000 || !ub_ok,
8974 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8975 color = getPixelColor(device, 480, 120);
8976 ok(color == 0x00ff0000 || !ub_ok,
8977 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8979 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8982 IDirect3DVertexBuffer9_Release(vb2);
8983 out:
8984 IDirect3DVertexBuffer9_Release(vb);
8985 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
8986 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
8987 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
8988 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
8989 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
8990 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
8991 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
8992 IDirect3DVertexDeclaration9_Release(dcl_positiont);
8993 refcount = IDirect3DDevice9_Release(device);
8994 ok(!refcount, "Device has %u references left.\n", refcount);
8995 done:
8996 IDirect3D9_Release(d3d);
8997 DestroyWindow(window);
9000 static void test_vshader_float16(void)
9002 IDirect3DVertexDeclaration9 *vdecl = NULL;
9003 IDirect3DVertexBuffer9 *buffer = NULL;
9004 IDirect3DVertexShader9 *shader;
9005 IDirect3DDevice9 *device;
9006 IDirect3D9 *d3d;
9007 ULONG refcount;
9008 D3DCAPS9 caps;
9009 DWORD color;
9010 HWND window;
9011 void *data;
9012 HRESULT hr;
9014 static const D3DVERTEXELEMENT9 decl_elements[] =
9016 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9017 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9018 D3DDECL_END()
9020 static const DWORD shader_code[] =
9022 0xfffe0101, /* vs_1_1 */
9023 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9024 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9025 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9026 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9027 0x0000ffff,
9029 static const struct vertex_float16color
9031 float x, y, z;
9032 DWORD c1, c2;
9034 quad[] =
9036 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9037 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9038 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9039 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9041 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9042 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9043 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9044 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9046 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9047 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9048 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9049 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9051 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9052 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9053 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9054 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9057 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9058 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9059 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9060 ok(!!d3d, "Failed to create a D3D object.\n");
9061 if (!(device = create_device(d3d, window, window, TRUE)))
9063 skip("Failed to create a D3D device, skipping tests.\n");
9064 goto done;
9067 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9068 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9069 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9071 skip("No vs_3_0 support, skipping tests.\n");
9072 IDirect3DDevice9_Release(device);
9073 goto done;
9076 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9077 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9079 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9080 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9081 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9082 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9083 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9084 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9086 hr = IDirect3DDevice9_BeginScene(device);
9087 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9088 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9089 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9091 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9092 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9093 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9094 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9095 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9097 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9098 hr = IDirect3DDevice9_EndScene(device);
9099 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9101 color = getPixelColor(device, 480, 360);
9102 ok(color == 0x00ff0000,
9103 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9104 color = getPixelColor(device, 160, 120);
9105 ok(color == 0x00000000,
9106 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9107 color = getPixelColor(device, 160, 360);
9108 ok(color == 0x0000ff00,
9109 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9110 color = getPixelColor(device, 480, 120);
9111 ok(color == 0x000000ff,
9112 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9113 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9115 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9116 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9118 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9119 D3DPOOL_MANAGED, &buffer, NULL);
9120 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9121 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9122 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9123 memcpy(data, quad, sizeof(quad));
9124 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9125 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9126 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9127 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9129 hr = IDirect3DDevice9_BeginScene(device);
9130 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9131 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9132 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9133 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9134 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9135 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9136 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9137 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9138 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9139 hr = IDirect3DDevice9_EndScene(device);
9140 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9142 color = getPixelColor(device, 480, 360);
9143 ok(color == 0x00ff0000,
9144 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9145 color = getPixelColor(device, 160, 120);
9146 ok(color == 0x00000000,
9147 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9148 color = getPixelColor(device, 160, 360);
9149 ok(color == 0x0000ff00,
9150 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9151 color = getPixelColor(device, 480, 120);
9152 ok(color == 0x000000ff,
9153 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9154 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9156 IDirect3DVertexDeclaration9_Release(vdecl);
9157 IDirect3DVertexShader9_Release(shader);
9158 IDirect3DVertexBuffer9_Release(buffer);
9159 refcount = IDirect3DDevice9_Release(device);
9160 ok(!refcount, "Device has %u references left.\n", refcount);
9161 done:
9162 IDirect3D9_Release(d3d);
9163 DestroyWindow(window);
9166 static void conditional_np2_repeat_test(void)
9168 IDirect3DTexture9 *texture;
9169 IDirect3DDevice9 *device;
9170 D3DLOCKED_RECT rect;
9171 unsigned int x, y;
9172 DWORD *dst, color;
9173 IDirect3D9 *d3d;
9174 ULONG refcount;
9175 D3DCAPS9 caps;
9176 HWND window;
9177 HRESULT hr;
9179 static const float quad[] =
9181 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9182 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9183 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9184 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9187 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9188 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9189 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9190 ok(!!d3d, "Failed to create a D3D object.\n");
9191 if (!(device = create_device(d3d, window, window, TRUE)))
9193 skip("Failed to create a D3D device, skipping tests.\n");
9194 goto done;
9197 memset(&caps, 0, sizeof(caps));
9198 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9199 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9200 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9202 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9203 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9204 "Card has conditional NP2 support without power of two restriction set\n");
9206 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9208 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9209 IDirect3DDevice9_Release(device);
9210 goto done;
9212 else
9214 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9215 IDirect3DDevice9_Release(device);
9216 goto done;
9219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9222 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9223 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9225 memset(&rect, 0, sizeof(rect));
9226 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9227 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9228 for(y = 0; y < 10; y++) {
9229 for(x = 0; x < 10; x++) {
9230 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9231 if(x == 0 || x == 9 || y == 0 || y == 9) {
9232 *dst = 0x00ff0000;
9233 } else {
9234 *dst = 0x000000ff;
9238 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9239 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9241 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9242 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9244 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9246 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9247 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9248 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9249 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9250 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9252 hr = IDirect3DDevice9_BeginScene(device);
9253 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9254 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9255 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9256 hr = IDirect3DDevice9_EndScene(device);
9257 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9259 color = getPixelColor(device, 1, 1);
9260 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9261 color = getPixelColor(device, 639, 479);
9262 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9264 color = getPixelColor(device, 135, 101);
9265 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9266 color = getPixelColor(device, 140, 101);
9267 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9268 color = getPixelColor(device, 135, 105);
9269 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9270 color = getPixelColor(device, 140, 105);
9271 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9273 color = getPixelColor(device, 135, 376);
9274 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9275 color = getPixelColor(device, 140, 376);
9276 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9277 color = getPixelColor(device, 135, 379);
9278 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9279 color = getPixelColor(device, 140, 379);
9280 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9282 color = getPixelColor(device, 500, 101);
9283 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9284 color = getPixelColor(device, 504, 101);
9285 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9286 color = getPixelColor(device, 500, 105);
9287 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9288 color = getPixelColor(device, 504, 105);
9289 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9291 color = getPixelColor(device, 500, 376);
9292 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9293 color = getPixelColor(device, 504, 376);
9294 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9295 color = getPixelColor(device, 500, 380);
9296 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9297 color = getPixelColor(device, 504, 380);
9298 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9300 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9302 IDirect3DTexture9_Release(texture);
9303 refcount = IDirect3DDevice9_Release(device);
9304 ok(!refcount, "Device has %u references left.\n", refcount);
9305 done:
9306 IDirect3D9_Release(d3d);
9307 DestroyWindow(window);
9310 static void vface_register_test(void)
9312 IDirect3DSurface9 *surface, *backbuffer;
9313 IDirect3DVertexShader9 *vshader;
9314 IDirect3DPixelShader9 *shader;
9315 IDirect3DTexture9 *texture;
9316 IDirect3DDevice9 *device;
9317 IDirect3D9 *d3d;
9318 ULONG refcount;
9319 D3DCAPS9 caps;
9320 DWORD color;
9321 HWND window;
9322 HRESULT hr;
9324 static const DWORD shader_code[] =
9326 0xffff0300, /* ps_3_0 */
9327 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9328 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9329 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9330 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9331 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9332 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9333 0x0000ffff /* END */
9335 static const DWORD vshader_code[] =
9337 0xfffe0300, /* vs_3_0 */
9338 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9339 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9340 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9341 0x0000ffff /* end */
9343 static const float quad[] =
9345 -1.0f, -1.0f, 0.1f,
9346 1.0f, -1.0f, 0.1f,
9347 -1.0f, 0.0f, 0.1f,
9349 1.0f, -1.0f, 0.1f,
9350 1.0f, 0.0f, 0.1f,
9351 -1.0f, 0.0f, 0.1f,
9353 -1.0f, 0.0f, 0.1f,
9354 -1.0f, 1.0f, 0.1f,
9355 1.0f, 0.0f, 0.1f,
9357 1.0f, 0.0f, 0.1f,
9358 -1.0f, 1.0f, 0.1f,
9359 1.0f, 1.0f, 0.1f,
9361 static const float blit[] =
9363 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9364 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9365 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9366 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9369 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9370 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9371 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9372 ok(!!d3d, "Failed to create a D3D object.\n");
9373 if (!(device = create_device(d3d, window, window, TRUE)))
9375 skip("Failed to create a D3D device, skipping tests.\n");
9376 goto done;
9379 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9380 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9381 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9383 skip("No shader model 3 support, skipping tests.\n");
9384 IDirect3DDevice9_Release(device);
9385 goto done;
9388 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9389 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9390 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9391 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9392 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9393 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9394 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9395 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9397 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9398 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9399 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9400 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9401 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9402 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9403 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9404 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9405 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9407 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9408 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9410 hr = IDirect3DDevice9_BeginScene(device);
9411 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9413 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9414 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9415 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9417 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9419 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9420 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9421 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9423 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9425 /* Blit the texture onto the back buffer to make it visible */
9426 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9427 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9428 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9429 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9430 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9431 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9432 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9433 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9434 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9435 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9436 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9437 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9439 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9441 hr = IDirect3DDevice9_EndScene(device);
9442 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9444 color = getPixelColor(device, 160, 360);
9445 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9446 color = getPixelColor(device, 160, 120);
9447 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9448 color = getPixelColor(device, 480, 360);
9449 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9450 color = getPixelColor(device, 480, 120);
9451 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9452 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9453 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9455 IDirect3DPixelShader9_Release(shader);
9456 IDirect3DVertexShader9_Release(vshader);
9457 IDirect3DSurface9_Release(surface);
9458 IDirect3DSurface9_Release(backbuffer);
9459 IDirect3DTexture9_Release(texture);
9460 refcount = IDirect3DDevice9_Release(device);
9461 ok(!refcount, "Device has %u references left.\n", refcount);
9462 done:
9463 IDirect3D9_Release(d3d);
9464 DestroyWindow(window);
9467 static void fixed_function_bumpmap_test(void)
9469 IDirect3DVertexDeclaration9 *vertex_declaration;
9470 IDirect3DTexture9 *texture, *tex1, *tex2;
9471 D3DLOCKED_RECT locked_rect;
9472 IDirect3DDevice9 *device;
9473 BOOL L6V5U5_supported;
9474 float scale, offset;
9475 IDirect3D9 *d3d;
9476 unsigned int i;
9477 D3DCOLOR color;
9478 ULONG refcount;
9479 D3DCAPS9 caps;
9480 HWND window;
9481 HRESULT hr;
9483 static const float quad[][7] =
9485 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9486 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9487 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9488 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9490 static const D3DVERTEXELEMENT9 decl_elements[] =
9492 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9493 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9494 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9495 D3DDECL_END()
9497 /* use asymmetric matrix to test loading */
9498 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9500 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9501 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9502 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9503 ok(!!d3d, "Failed to create a D3D object.\n");
9504 if (!(device = create_device(d3d, window, window, TRUE)))
9506 skip("Failed to create a D3D device, skipping tests.\n");
9507 goto done;
9510 memset(&caps, 0, sizeof(caps));
9511 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9512 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9513 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9515 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9516 IDirect3DDevice9_Release(device);
9517 goto done;
9520 /* This check is disabled, some Windows drivers do not handle
9521 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9522 * supported, but after that bump mapping works properly. So just test if
9523 * the format is generally supported, and check the BUMPENVMAP flag. */
9524 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9525 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9526 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9527 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9529 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9530 IDirect3DDevice9_Release(device);
9531 return;
9534 /* Generate the textures */
9535 generate_bumpmap_textures(device);
9537 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9538 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9539 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9540 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9541 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9542 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9543 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9544 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9546 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9547 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9548 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9549 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9550 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9551 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9553 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9554 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9555 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9556 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9557 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9558 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9560 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9561 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9563 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9564 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9566 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9567 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9569 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9570 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9571 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9572 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9574 hr = IDirect3DDevice9_BeginScene(device);
9575 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9578 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9580 hr = IDirect3DDevice9_EndScene(device);
9581 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9583 color = getPixelColor(device, 240, 60);
9584 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9585 color = getPixelColor(device, 400, 60);
9586 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9587 color = getPixelColor(device, 80, 180);
9588 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9589 color = getPixelColor(device, 560, 180);
9590 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9591 color = getPixelColor(device, 80, 300);
9592 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9593 color = getPixelColor(device, 560, 300);
9594 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9595 color = getPixelColor(device, 240, 420);
9596 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9597 color = getPixelColor(device, 400, 420);
9598 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9600 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9602 for(i = 0; i < 2; i++) {
9603 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9604 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9605 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9606 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9607 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9608 IDirect3DTexture9_Release(texture); /* To destroy it */
9611 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9613 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9614 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9615 IDirect3DDevice9_Release(device);
9616 goto done;
9619 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9620 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9621 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9622 * would only make this test more complicated
9624 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9625 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9626 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9627 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9629 memset(&locked_rect, 0, sizeof(locked_rect));
9630 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9631 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9632 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9633 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9634 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9636 memset(&locked_rect, 0, sizeof(locked_rect));
9637 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9638 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9639 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9640 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9641 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9643 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9644 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9645 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9646 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9648 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9649 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9650 scale = 2.0;
9651 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9652 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9653 offset = 0.1;
9654 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9655 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9657 hr = IDirect3DDevice9_BeginScene(device);
9658 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9660 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9661 hr = IDirect3DDevice9_EndScene(device);
9662 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9664 color = getPixelColor(device, 320, 240);
9665 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9666 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9667 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9669 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9670 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9671 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9673 /* Check a result scale factor > 1.0 */
9674 scale = 10;
9675 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9676 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9677 offset = 10;
9678 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9679 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9681 hr = IDirect3DDevice9_BeginScene(device);
9682 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9684 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9685 hr = IDirect3DDevice9_EndScene(device);
9686 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9688 color = getPixelColor(device, 320, 240);
9689 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9690 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9691 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9693 /* Check clamping in the scale factor calculation */
9694 scale = 1000;
9695 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9696 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9697 offset = -1;
9698 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9699 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9701 hr = IDirect3DDevice9_BeginScene(device);
9702 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9704 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9705 hr = IDirect3DDevice9_EndScene(device);
9706 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9708 color = getPixelColor(device, 320, 240);
9709 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9710 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9711 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9713 IDirect3DTexture9_Release(tex1);
9714 IDirect3DTexture9_Release(tex2);
9715 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9716 refcount = IDirect3DDevice9_Release(device);
9717 ok(!refcount, "Device has %u references left.\n", refcount);
9718 done:
9719 IDirect3D9_Release(d3d);
9720 DestroyWindow(window);
9723 static void stencil_cull_test(void)
9725 IDirect3DDevice9 *device;
9726 IDirect3D9 *d3d;
9727 ULONG refcount;
9728 D3DCAPS9 caps;
9729 HWND window;
9730 HRESULT hr;
9731 static const float quad1[] =
9733 -1.0, -1.0, 0.1,
9734 0.0, -1.0, 0.1,
9735 -1.0, 0.0, 0.1,
9736 0.0, 0.0, 0.1,
9738 static const float quad2[] =
9740 0.0, -1.0, 0.1,
9741 1.0, -1.0, 0.1,
9742 0.0, 0.0, 0.1,
9743 1.0, 0.0, 0.1,
9745 static const float quad3[] =
9747 0.0, 0.0, 0.1,
9748 1.0, 0.0, 0.1,
9749 0.0, 1.0, 0.1,
9750 1.0, 1.0, 0.1,
9752 static const float quad4[] =
9754 -1.0, 0.0, 0.1,
9755 0.0, 0.0, 0.1,
9756 -1.0, 1.0, 0.1,
9757 0.0, 1.0, 0.1,
9759 struct
9761 struct vec3 position;
9762 DWORD diffuse;
9764 painter[] =
9766 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
9767 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
9768 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
9769 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
9771 static const WORD indices_cw[] = {0, 1, 3};
9772 static const WORD indices_ccw[] = {0, 2, 3};
9773 unsigned int i;
9774 DWORD color;
9776 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9777 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9778 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9779 ok(!!d3d, "Failed to create a D3D object.\n");
9780 if (!(device = create_device(d3d, window, window, TRUE)))
9782 skip("Cannot create a device with a D24S8 stencil buffer.\n");
9783 DestroyWindow(window);
9784 IDirect3D9_Release(d3d);
9785 return;
9787 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9788 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9789 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
9791 skip("No two sided stencil support\n");
9792 goto cleanup;
9795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
9796 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9797 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9798 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
9800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9801 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
9802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9803 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
9804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
9805 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
9807 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
9809 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
9811 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
9814 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
9816 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
9818 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
9821 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9823 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9825 /* First pass: Fill the stencil buffer with some values... */
9826 hr = IDirect3DDevice9_BeginScene(device);
9827 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9830 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9831 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9832 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9833 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9834 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9835 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
9839 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9840 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9841 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9842 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9843 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9844 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9845 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9846 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9847 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9850 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9851 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9852 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9853 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9854 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9855 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9856 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
9859 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9860 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9861 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9862 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9863 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9864 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9865 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9867 hr = IDirect3DDevice9_EndScene(device);
9868 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
9871 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
9873 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
9875 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9877 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
9881 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9883 /* 2nd pass: Make the stencil values visible */
9884 hr = IDirect3DDevice9_BeginScene(device);
9885 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9886 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9887 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9888 for (i = 0; i < 16; ++i)
9890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
9891 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9893 painter[0].diffuse = (i * 16); /* Creates shades of blue */
9894 painter[1].diffuse = (i * 16);
9895 painter[2].diffuse = (i * 16);
9896 painter[3].diffuse = (i * 16);
9897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
9898 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9900 hr = IDirect3DDevice9_EndScene(device);
9901 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9903 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9904 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9906 color = getPixelColor(device, 160, 420);
9907 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
9908 color = getPixelColor(device, 160, 300);
9909 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9911 color = getPixelColor(device, 480, 420);
9912 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
9913 color = getPixelColor(device, 480, 300);
9914 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
9916 color = getPixelColor(device, 160, 180);
9917 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
9918 color = getPixelColor(device, 160, 60);
9919 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
9921 color = getPixelColor(device, 480, 180);
9922 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
9923 color = getPixelColor(device, 480, 60);
9924 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9927 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9929 cleanup:
9930 refcount = IDirect3DDevice9_Release(device);
9931 ok(!refcount, "Device has %u references left.\n", refcount);
9932 IDirect3D9_Release(d3d);
9933 DestroyWindow(window);
9936 static void test_fragment_coords(void)
9938 IDirect3DSurface9 *surface = NULL, *backbuffer;
9939 IDirect3DPixelShader9 *shader, *shader_frac;
9940 IDirect3DVertexShader9 *vshader;
9941 IDirect3DDevice9 *device;
9942 D3DLOCKED_RECT lr;
9943 IDirect3D9 *d3d;
9944 ULONG refcount;
9945 D3DCAPS9 caps;
9946 DWORD color;
9947 HWND window;
9948 HRESULT hr;
9949 DWORD *pos;
9951 static const DWORD shader_code[] =
9953 0xffff0300, /* ps_3_0 */
9954 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9955 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
9956 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
9957 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
9958 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
9959 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
9960 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
9961 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
9962 0x0000ffff /* end */
9964 static const DWORD shader_frac_code[] =
9966 0xffff0300, /* ps_3_0 */
9967 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
9968 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9969 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
9970 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
9971 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9972 0x0000ffff /* end */
9974 static const DWORD vshader_code[] =
9976 0xfffe0300, /* vs_3_0 */
9977 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9978 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9979 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9980 0x0000ffff /* end */
9982 static const float quad[] =
9984 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9985 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9986 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9987 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9989 float constant[4] = {1.0, 0.0, 320, 240};
9991 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9992 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9993 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9994 ok(!!d3d, "Failed to create a D3D object.\n");
9995 if (!(device = create_device(d3d, window, window, TRUE)))
9997 skip("Failed to create a D3D device, skipping tests.\n");
9998 goto done;
10001 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10002 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10003 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10005 skip("No shader model 3 support, skipping tests.\n");
10006 IDirect3DDevice9_Release(device);
10007 goto done;
10010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10012 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10013 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10014 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10015 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10016 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10017 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10018 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10019 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10020 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10021 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10022 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10023 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10024 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10025 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10027 hr = IDirect3DDevice9_BeginScene(device);
10028 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10029 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10030 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10032 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10033 hr = IDirect3DDevice9_EndScene(device);
10034 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10036 /* This has to be pixel exact */
10037 color = getPixelColor(device, 319, 239);
10038 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10039 color = getPixelColor(device, 320, 239);
10040 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10041 color = getPixelColor(device, 319, 240);
10042 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10043 color = getPixelColor(device, 320, 240);
10044 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10045 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10047 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10048 &surface, NULL);
10049 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10050 hr = IDirect3DDevice9_BeginScene(device);
10051 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10052 constant[2] = 16; constant[3] = 16;
10053 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10054 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10055 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10056 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10058 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10059 hr = IDirect3DDevice9_EndScene(device);
10060 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10062 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10063 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10065 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10066 color = *pos & 0x00ffffff;
10067 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10068 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10069 color = *pos & 0x00ffffff;
10070 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10071 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10072 color = *pos & 0x00ffffff;
10073 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10074 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10075 color = *pos & 0x00ffffff;
10076 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10078 hr = IDirect3DSurface9_UnlockRect(surface);
10079 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10081 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10082 * have full control over the multisampling setting inside this test
10084 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10085 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10086 hr = IDirect3DDevice9_BeginScene(device);
10087 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10088 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10089 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10091 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10092 hr = IDirect3DDevice9_EndScene(device);
10093 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10095 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10096 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10098 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10099 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10101 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10102 color = *pos & 0x00ffffff;
10103 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10105 hr = IDirect3DSurface9_UnlockRect(surface);
10106 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10108 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10109 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10110 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10112 IDirect3DPixelShader9_Release(shader);
10113 IDirect3DPixelShader9_Release(shader_frac);
10114 IDirect3DVertexShader9_Release(vshader);
10115 if(surface) IDirect3DSurface9_Release(surface);
10116 IDirect3DSurface9_Release(backbuffer);
10117 refcount = IDirect3DDevice9_Release(device);
10118 ok(!refcount, "Device has %u references left.\n", refcount);
10119 done:
10120 IDirect3D9_Release(d3d);
10121 DestroyWindow(window);
10124 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10126 D3DCOLOR color;
10128 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10129 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10130 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10131 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10132 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10134 ++r;
10135 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10136 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10137 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10138 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10139 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10141 return TRUE;
10144 static void pointsize_test(void)
10146 static const float a = 0.5f, b = 0.5f, c = 0.5f;
10147 float ptsize, ptsizemax_orig, ptsizemin_orig;
10148 IDirect3DSurface9 *rt, *backbuffer;
10149 IDirect3DTexture9 *tex1, *tex2;
10150 IDirect3DDevice9 *device;
10151 IDirect3DVertexShader9 *vs;
10152 IDirect3DPixelShader9 *ps;
10153 D3DLOCKED_RECT lr;
10154 IDirect3D9 *d3d;
10155 D3DCOLOR color;
10156 ULONG refcount;
10157 D3DCAPS9 caps;
10158 HWND window;
10159 HRESULT hr;
10160 unsigned int i, j;
10162 static const RECT rect = {0, 0, 128, 128};
10163 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10164 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10165 static const float vertices[] =
10167 64.0f, 64.0f, 0.1f,
10168 128.0f, 64.0f, 0.1f,
10169 192.0f, 64.0f, 0.1f,
10170 256.0f, 64.0f, 0.1f,
10171 320.0f, 64.0f, 0.1f,
10172 384.0f, 64.0f, 0.1f,
10173 448.0f, 64.0f, 0.1f,
10174 512.0f, 64.0f, 0.1f,
10176 static const struct
10178 float x, y, z;
10179 float point_size;
10181 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10182 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10183 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10184 static const DWORD vshader_code[] =
10186 0xfffe0101, /* vs_1_1 */
10187 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10188 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10189 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10190 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10191 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10192 0x0000ffff
10194 static const DWORD vshader_psize_code[] =
10196 0xfffe0101, /* vs_1_1 */
10197 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10198 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10199 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10200 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10201 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10202 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10203 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10204 0x0000ffff
10206 static const DWORD pshader_code[] =
10208 0xffff0101, /* ps_1_1 */
10209 0x00000042, 0xb00f0000, /* tex t0 */
10210 0x00000042, 0xb00f0001, /* tex t1 */
10211 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10212 0x0000ffff
10214 static const DWORD pshader2_code[] =
10216 0xffff0200, /* ps_2_0 */
10217 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10218 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10219 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10220 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10221 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10222 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10223 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10224 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10225 0x0000ffff
10227 static const DWORD pshader2_zw_code[] =
10229 0xffff0200, /* ps_2_0 */
10230 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10231 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10232 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10233 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10234 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10235 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10236 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10237 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10238 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10239 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10240 0x0000ffff
10242 static const DWORD vshader3_code[] =
10244 0xfffe0300, /* vs_3_0 */
10245 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10246 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10247 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10248 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10249 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10250 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10251 0x0000ffff
10253 static const DWORD vshader3_psize_code[] =
10255 0xfffe0300, /* vs_3_0 */
10256 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10257 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10258 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10259 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10260 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10261 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10262 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10263 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10264 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10265 0x0000ffff
10267 static const DWORD pshader3_code[] =
10269 0xffff0300, /* ps_3_0 */
10270 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10271 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10272 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10273 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10274 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10275 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10276 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10277 0x0000ffff
10279 static const DWORD pshader3_zw_code[] =
10281 0xffff0300, /* ps_3_0 */
10282 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10283 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10284 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10285 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10286 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10287 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10288 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10289 0x0000ffff
10291 static const struct test_shader
10293 DWORD version;
10294 const DWORD *code;
10296 novs = {0, NULL},
10297 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10298 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10299 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10300 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10301 nops = {0, NULL},
10302 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10303 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10304 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10305 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10306 ps3_zw = {D3DVS_VERSION(3, 0), pshader3_zw_code};
10307 static const struct
10309 const struct test_shader *vs;
10310 const struct test_shader *ps;
10311 DWORD accepted_fvf;
10312 unsigned int nonscaled_size, scaled_size;
10313 BOOL gives_0_0_texcoord;
10314 BOOL allow_broken;
10316 test_setups[] =
10318 {&novs, &nops, D3DFVF_XYZ, 32, 62, FALSE, FALSE},
10319 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10320 {&novs, &ps1, D3DFVF_XYZ, 32, 62, FALSE, FALSE},
10321 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10322 {&novs, &ps2, D3DFVF_XYZ, 32, 62, FALSE, TRUE},
10323 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 62, TRUE, FALSE},
10324 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10325 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10326 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10327 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10328 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48, FALSE, FALSE},
10329 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10330 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10332 static const struct
10334 BOOL zero_size;
10335 BOOL scale;
10336 BOOL override_min;
10337 DWORD fvf;
10338 const void *vertex_data;
10339 unsigned int vertex_size;
10341 tests[] =
10343 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10344 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10345 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10346 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10347 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10348 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10349 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10350 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10352 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10353 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10354 D3DMATRIX matrix =
10356 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10357 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10358 0.0f, 0.0f, 1.0f, 0.0f,
10359 -1.0f, 1.0f, 0.0f, 1.0f,
10360 }}};
10362 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10363 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10364 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10365 ok(!!d3d, "Failed to create a D3D object.\n");
10366 if (!(device = create_device(d3d, window, window, TRUE)))
10368 skip("Failed to create a D3D device, skipping tests.\n");
10369 goto done;
10372 memset(&caps, 0, sizeof(caps));
10373 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10374 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10375 if(caps.MaxPointSize < 32.0) {
10376 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10377 IDirect3DDevice9_Release(device);
10378 goto done;
10381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10384 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10385 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10387 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10388 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10390 hr = IDirect3DDevice9_BeginScene(device);
10391 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10393 ptsize = 15.0f;
10394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10395 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10397 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10399 ptsize = 31.0f;
10400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10401 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10403 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10405 ptsize = 30.75f;
10406 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10407 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10409 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10411 if (caps.MaxPointSize >= 63.0f)
10413 ptsize = 63.0f;
10414 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10415 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10416 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10417 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10419 ptsize = 62.75f;
10420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10421 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10423 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10426 ptsize = 1.0f;
10427 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10428 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10430 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10432 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10433 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10434 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10435 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10437 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10438 ptsize = 15.0f;
10439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10440 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10441 ptsize = 1.0f;
10442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10443 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10445 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10448 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10450 /* pointsize < pointsize_min < pointsize_max?
10451 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10452 ptsize = 1.0f;
10453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10454 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10455 ptsize = 15.0f;
10456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10457 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10459 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10462 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10464 hr = IDirect3DDevice9_EndScene(device);
10465 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10467 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10468 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10469 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10471 if (caps.MaxPointSize >= 63.0)
10473 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10474 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10477 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10478 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10479 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10480 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10481 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10483 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10485 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10486 * generates texture coordinates for the point(result: Yes, it does)
10488 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10489 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10490 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10492 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10493 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10495 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10496 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10497 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10498 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10499 memset(&lr, 0, sizeof(lr));
10500 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10501 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10502 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10503 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10504 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10505 memset(&lr, 0, sizeof(lr));
10506 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10507 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10508 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10509 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10510 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10511 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10512 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10513 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10514 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10515 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10516 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10517 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10518 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10519 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10520 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10521 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10522 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10523 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10524 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10528 ptsize = 32.0;
10529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10530 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10532 hr = IDirect3DDevice9_BeginScene(device);
10533 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10536 hr = IDirect3DDevice9_EndScene(device);
10537 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10539 color = getPixelColor(device, 64-4, 64-4);
10540 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10541 color = getPixelColor(device, 64-4, 64+4);
10542 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10543 color = getPixelColor(device, 64+4, 64+4);
10544 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10545 color = getPixelColor(device, 64+4, 64-4);
10546 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10547 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10549 U(matrix).m[0][0] = 1.0f / 64.0f;
10550 U(matrix).m[1][1] = -1.0f / 64.0f;
10551 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10552 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10554 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10555 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10557 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10558 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10559 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10562 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10564 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10566 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10567 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10568 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10570 if (caps.MaxPointSize < 63.0f)
10572 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10573 goto cleanup;
10576 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10578 if (caps.VertexShaderVersion < test_setups[i].vs->version
10579 || caps.PixelShaderVersion < test_setups[i].ps->version)
10581 skip("Vertex / pixel shader version not supported, skipping test.\n");
10582 continue;
10584 if (test_setups[i].vs->code)
10586 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10587 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10589 else
10591 vs = NULL;
10593 if (test_setups[i].ps->code)
10595 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10596 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10598 else
10600 ps = NULL;
10603 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10604 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10605 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10606 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10608 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10610 BOOL allow_broken = test_setups[i].allow_broken;
10611 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10612 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10614 if (test_setups[i].accepted_fvf != tests[j].fvf)
10615 continue;
10617 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10619 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10621 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10622 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10623 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10626 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10628 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10629 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10631 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10632 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10633 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10634 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10636 hr = IDirect3DDevice9_BeginScene(device);
10637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10639 tests[j].vertex_data, tests[j].vertex_size);
10640 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10641 hr = IDirect3DDevice9_EndScene(device);
10642 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10644 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10645 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10646 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10647 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10649 if (tests[j].zero_size)
10651 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10652 * it does the "useful" thing on all the drivers I tried. */
10653 /* On WARP it does draw some pixels, most of the time. */
10654 color = getPixelColor(device, 64, 64);
10655 ok(color_match(color, 0x0000ffff, 0)
10656 || broken(color_match(color, 0x00ff0000, 0))
10657 || broken(color_match(color, 0x00ffff00, 0))
10658 || broken(color_match(color, 0x00000000, 0))
10659 || broken(color_match(color, 0x0000ff00, 0)),
10660 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10662 else
10664 /* On AMD apparently only the first texcoord is modified by the point coordinates
10665 * when using SM2/3 pixel shaders. */
10666 color = getPixelColor(device, 64 - size / 2 + 1, 64 - size / 2 + 1);
10667 ok(color_match(color, 0x00ff0000, 0),
10668 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10669 color = getPixelColor(device, 64 + size / 2 - 1, 64 - size / 2 + 1);
10670 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10671 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10672 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10673 color = getPixelColor(device, 64 - size / 2 + 1, 64 + size / 2 - 1);
10674 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10675 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10676 color = getPixelColor(device, 64 + size / 2 - 1, 64 + size / 2 - 1);
10677 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10678 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10679 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10681 color = getPixelColor(device, 64 - size / 2 - 1, 64 - size / 2 - 1);
10682 ok(color_match(color, 0x0000ffff, 0),
10683 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10684 color = getPixelColor(device, 64 + size / 2 + 1, 64 - size / 2 - 1);
10685 ok(color_match(color, 0x0000ffff, 0),
10686 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10687 color = getPixelColor(device, 64 - size / 2 - 1, 64 + size / 2 + 1);
10688 ok(color_match(color, 0x0000ffff, 0),
10689 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10690 color = getPixelColor(device, 64 + size / 2 + 1, 64 + size / 2 + 1);
10691 ok(color_match(color, 0x0000ffff, 0),
10692 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10695 IDirect3DDevice9_SetVertexShader(device, NULL);
10696 IDirect3DDevice9_SetPixelShader(device, NULL);
10697 if (vs)
10698 IDirect3DVertexShader9_Release(vs);
10699 if (ps)
10700 IDirect3DVertexShader9_Release(ps);
10703 cleanup:
10704 IDirect3DSurface9_Release(backbuffer);
10705 IDirect3DSurface9_Release(rt);
10707 IDirect3DTexture9_Release(tex1);
10708 IDirect3DTexture9_Release(tex2);
10709 refcount = IDirect3DDevice9_Release(device);
10710 ok(!refcount, "Device has %u references left.\n", refcount);
10711 done:
10712 IDirect3D9_Release(d3d);
10713 DestroyWindow(window);
10716 static void multiple_rendertargets_test(void)
10718 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
10719 IDirect3DPixelShader9 *ps1, *ps2;
10720 IDirect3DTexture9 *tex1, *tex2;
10721 IDirect3DVertexShader9 *vs;
10722 IDirect3DDevice9 *device;
10723 IDirect3D9 *d3d;
10724 ULONG refcount;
10725 D3DCAPS9 caps;
10726 DWORD color;
10727 HWND window;
10728 HRESULT hr;
10729 UINT i, j;
10731 static const DWORD vshader_code[] =
10733 0xfffe0300, /* vs_3_0 */
10734 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10735 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10736 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10737 0x0000ffff /* end */
10739 static const DWORD pshader_code1[] =
10741 0xffff0300, /* ps_3_0 */
10742 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10743 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10744 0x0000ffff /* end */
10746 static const DWORD pshader_code2[] =
10748 0xffff0300, /* ps_3_0 */
10749 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10750 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
10751 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10752 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
10753 0x0000ffff /* end */
10755 static const float quad[] =
10757 -1.0f, -1.0f, 0.1f,
10758 -1.0f, 1.0f, 0.1f,
10759 1.0f, -1.0f, 0.1f,
10760 1.0f, 1.0f, 0.1f,
10762 static const float texquad[] =
10764 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10765 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10766 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10767 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10769 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10770 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10771 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10772 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10775 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10776 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10777 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10778 ok(!!d3d, "Failed to create a D3D object.\n");
10779 if (!(device = create_device(d3d, window, window, TRUE)))
10781 skip("Failed to create a D3D device, skipping tests.\n");
10782 goto done;
10785 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10786 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10787 if (caps.NumSimultaneousRTs < 2)
10789 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
10790 IDirect3DDevice9_Release(device);
10791 goto done;
10793 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10795 skip("No shader model 3 support, skipping tests.\n");
10796 IDirect3DDevice9_Release(device);
10797 goto done;
10800 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
10801 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10803 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
10804 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
10805 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
10807 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10808 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
10809 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10810 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10811 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
10812 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10813 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
10814 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
10815 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
10816 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10817 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
10818 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10820 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
10821 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
10822 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
10823 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10824 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
10825 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10827 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10828 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10829 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
10830 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10831 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
10832 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10833 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10834 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10836 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10837 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10838 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10839 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10840 color = getPixelColorFromSurface(readback, 8, 8);
10841 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10842 "Expected color 0x000000ff, got 0x%08x.\n", color);
10843 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10844 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10845 color = getPixelColorFromSurface(readback, 8, 8);
10846 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10847 "Expected color 0x000000ff, got 0x%08x.\n", color);
10849 /* Render targets not written by the pixel shader should be unmodified. */
10850 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
10851 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_BeginScene(device);
10853 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10855 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10856 hr = IDirect3DDevice9_EndScene(device);
10857 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10858 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10859 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10860 color = getPixelColorFromSurface(readback, 8, 8);
10861 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10862 "Expected color 0xff00ff00, got 0x%08x.\n", color);
10863 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10864 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10865 for (i = 6; i < 10; ++i)
10867 for (j = 6; j < 10; ++j)
10869 color = getPixelColorFromSurface(readback, j, i);
10870 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10871 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
10875 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
10876 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10877 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10878 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10879 color = getPixelColorFromSurface(readback, 8, 8);
10880 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10881 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10882 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10883 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10884 color = getPixelColorFromSurface(readback, 8, 8);
10885 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10886 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10888 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
10889 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10891 hr = IDirect3DDevice9_BeginScene(device);
10892 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10895 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10897 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10898 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10899 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10900 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10901 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10902 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10903 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
10904 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10905 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
10906 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10908 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10910 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10911 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
10913 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10915 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
10916 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
10918 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10920 hr = IDirect3DDevice9_EndScene(device);
10921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10923 color = getPixelColor(device, 160, 240);
10924 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
10925 color = getPixelColor(device, 480, 240);
10926 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
10927 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10929 IDirect3DPixelShader9_Release(ps2);
10930 IDirect3DPixelShader9_Release(ps1);
10931 IDirect3DVertexShader9_Release(vs);
10932 IDirect3DTexture9_Release(tex1);
10933 IDirect3DTexture9_Release(tex2);
10934 IDirect3DSurface9_Release(surf1);
10935 IDirect3DSurface9_Release(surf2);
10936 IDirect3DSurface9_Release(backbuf);
10937 IDirect3DSurface9_Release(readback);
10938 refcount = IDirect3DDevice9_Release(device);
10939 ok(!refcount, "Device has %u references left.\n", refcount);
10940 done:
10941 IDirect3D9_Release(d3d);
10942 DestroyWindow(window);
10945 static void pixelshader_blending_test(void)
10947 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
10948 IDirect3DTexture9 *offscreenTexture = NULL;
10949 IDirect3DDevice9 *device;
10950 IDirect3D9 *d3d;
10951 ULONG refcount;
10952 int fmt_index;
10953 DWORD color;
10954 HWND window;
10955 HRESULT hr;
10957 static const struct
10959 const char *fmtName;
10960 D3DFORMAT textureFormat;
10961 D3DCOLOR resultColorBlending;
10962 D3DCOLOR resultColorNoBlending;
10964 test_formats[] =
10966 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
10967 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
10968 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff},
10969 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000},
10970 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
10971 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff},
10972 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000},
10974 static const float quad[][5] =
10976 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
10977 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
10978 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
10979 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
10981 static const struct
10983 struct vec3 position;
10984 DWORD diffuse;
10986 /* Quad with R=0x10, G=0x20 */
10987 quad1[] =
10989 {{-1.0f, -1.0f, 0.1f}, 0x80102000},
10990 {{-1.0f, 1.0f, 0.1f}, 0x80102000},
10991 {{ 1.0f, -1.0f, 0.1f}, 0x80102000},
10992 {{ 1.0f, 1.0f, 0.1f}, 0x80102000},
10994 /* Quad with R=0x20, G=0x10 */
10995 quad2[] =
10997 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
10998 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
10999 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11000 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11003 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11004 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11005 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11006 ok(!!d3d, "Failed to create a D3D object.\n");
11007 if (!(device = create_device(d3d, window, window, TRUE)))
11009 skip("Failed to create a D3D device, skipping tests.\n");
11010 goto done;
11013 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11014 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11016 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11018 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11020 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11021 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11023 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11024 continue;
11027 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11028 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11030 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11031 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11032 if(!offscreenTexture) {
11033 continue;
11036 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11037 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11038 if(!offscreen) {
11039 continue;
11042 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11043 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11045 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11046 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11048 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11049 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11050 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11051 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11052 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11054 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11056 /* Below we will draw two quads with different colors and try to blend
11057 * them together. The result color is compared with the expected
11058 * outcome. */
11059 hr = IDirect3DDevice9_BeginScene(device);
11060 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11062 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11063 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11065 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11068 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11070 /* Draw a quad using color 0x0010200. */
11071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11072 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11074 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11076 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11078 /* Draw a quad using color 0x0020100. */
11079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11080 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11082 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11084 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11086 /* We don't want to blend the result on the backbuffer. */
11087 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11088 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11090 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11091 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11092 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11093 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11094 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11097 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11099 /* This time with the texture. */
11100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11101 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11103 hr = IDirect3DDevice9_EndScene(device);
11104 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11106 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11107 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11109 /* Compare the color of the center quad with our expectation. */
11110 color = getPixelColor(device, 320, 240);
11111 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11112 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11113 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11115 else
11117 /* No pixel shader blending is supported so expect garbage. The
11118 * type of 'garbage' depends on the driver version and OS. E.g. on
11119 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11120 * modern ones 0x002010ff which is also what NVIDIA reports. On
11121 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11122 color = getPixelColor(device, 320, 240);
11123 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11124 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11125 test_formats[fmt_index].fmtName, color);
11127 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11129 IDirect3DDevice9_SetTexture(device, 0, NULL);
11130 if(offscreenTexture) {
11131 IDirect3DTexture9_Release(offscreenTexture);
11133 if(offscreen) {
11134 IDirect3DSurface9_Release(offscreen);
11138 IDirect3DSurface9_Release(backbuffer);
11139 refcount = IDirect3DDevice9_Release(device);
11140 ok(!refcount, "Device has %u references left.\n", refcount);
11141 done:
11142 IDirect3D9_Release(d3d);
11143 DestroyWindow(window);
11146 static void tssargtemp_test(void)
11148 IDirect3DDevice9 *device;
11149 IDirect3D9 *d3d;
11150 D3DCOLOR color;
11151 ULONG refcount;
11152 D3DCAPS9 caps;
11153 HWND window;
11154 HRESULT hr;
11156 static const struct
11158 struct vec3 position;
11159 DWORD diffuse;
11161 quad[] =
11163 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11164 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11165 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11166 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11169 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11170 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11171 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11172 ok(!!d3d, "Failed to create a D3D object.\n");
11173 if (!(device = create_device(d3d, window, window, TRUE)))
11175 skip("Failed to create a D3D device, skipping tests.\n");
11176 goto done;
11179 memset(&caps, 0, sizeof(caps));
11180 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11181 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11182 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11183 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11184 IDirect3DDevice9_Release(device);
11185 goto done;
11188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11189 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11191 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11192 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11193 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11194 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11196 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11197 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11198 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11199 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11200 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11201 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11203 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11204 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11205 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11206 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11207 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11208 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11210 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11211 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11216 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11217 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11218 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11220 hr = IDirect3DDevice9_BeginScene(device);
11221 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_EndScene(device);
11225 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11227 color = getPixelColor(device, 320, 240);
11228 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11229 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11231 refcount = IDirect3DDevice9_Release(device);
11232 ok(!refcount, "Device has %u references left.\n", refcount);
11233 done:
11234 IDirect3D9_Release(d3d);
11235 DestroyWindow(window);
11238 /* Drawing Indexed Geometry with instances*/
11239 static void stream_test(void)
11241 IDirect3DVertexDeclaration9 *pDecl = NULL;
11242 IDirect3DVertexShader9 *shader = NULL;
11243 IDirect3DVertexBuffer9 *vb3 = NULL;
11244 IDirect3DVertexBuffer9 *vb2 = NULL;
11245 IDirect3DVertexBuffer9 *vb = NULL;
11246 IDirect3DIndexBuffer9 *ib = NULL;
11247 IDirect3DDevice9 *device;
11248 IDirect3D9 *d3d;
11249 ULONG refcount;
11250 D3DCAPS9 caps;
11251 DWORD color;
11252 HWND window;
11253 unsigned i;
11254 HRESULT hr;
11255 BYTE *data;
11256 DWORD ind;
11258 static const struct testdata
11260 DWORD idxVertex; /* number of instances in the first stream */
11261 DWORD idxColor; /* number of instances in the second stream */
11262 DWORD idxInstance; /* should be 1 ?? */
11263 DWORD color1; /* color 1 instance */
11264 DWORD color2; /* color 2 instance */
11265 DWORD color3; /* color 3 instance */
11266 DWORD color4; /* color 4 instance */
11267 WORD strVertex; /* specify which stream to use 0-2*/
11268 WORD strColor;
11269 WORD strInstance;
11271 testcases[]=
11273 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11274 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11275 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11276 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11277 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11278 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11279 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11280 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11281 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11282 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11283 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11284 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11285 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11286 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11287 #if 0
11288 /* This draws one instance on some machines, no instance on others. */
11289 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11290 /* This case is handled in a stand alone test,
11291 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11292 * return D3DERR_INVALIDCALL. */
11293 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11294 #endif
11296 static const DWORD shader_code[] =
11298 0xfffe0101, /* vs_1_1 */
11299 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11300 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11301 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11302 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11303 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11304 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11305 0x0000ffff
11307 static const float quad[][3] =
11309 {-0.5f, -0.5f, 1.1f}, /*0 */
11310 {-0.5f, 0.5f, 1.1f}, /*1 */
11311 { 0.5f, -0.5f, 1.1f}, /*2 */
11312 { 0.5f, 0.5f, 1.1f}, /*3 */
11314 static const float vertcolor[][4] =
11316 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11317 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11318 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11319 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11321 /* 4 position for 4 instances */
11322 static const float instancepos[][3] =
11324 {-0.6f,-0.6f, 0.0f},
11325 { 0.6f,-0.6f, 0.0f},
11326 { 0.6f, 0.6f, 0.0f},
11327 {-0.6f, 0.6f, 0.0f},
11329 static const short indices[] = {0, 1, 2, 2, 1, 3};
11330 D3DVERTEXELEMENT9 decl[] =
11332 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11333 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11334 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11335 D3DDECL_END()
11338 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11339 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11340 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11341 ok(!!d3d, "Failed to create a D3D object.\n");
11342 if (!(device = create_device(d3d, window, window, TRUE)))
11344 skip("Failed to create a D3D device, skipping tests.\n");
11345 goto done;
11348 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11349 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11350 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11352 skip("No vs_3_0 support, skipping tests.\n");
11353 IDirect3DDevice9_Release(device);
11354 goto done;
11357 /* set the default value because it isn't done in wine? */
11358 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11359 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11361 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11362 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11363 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11365 /* check wrong cases */
11366 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11367 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11368 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11369 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11370 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11371 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11372 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11373 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11374 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11375 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11376 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11377 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11378 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11379 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11380 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11381 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11382 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11383 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11384 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11385 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11387 /* set the default value back */
11388 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11389 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11391 /* create all VertexBuffers*/
11392 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11393 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11394 if(!vb) {
11395 skip("Failed to create a vertex buffer\n");
11396 IDirect3DDevice9_Release(device);
11397 goto done;
11399 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11400 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11401 if(!vb2) {
11402 skip("Failed to create a vertex buffer\n");
11403 goto out;
11405 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11406 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11407 if(!vb3) {
11408 skip("Failed to create a vertex buffer\n");
11409 goto out;
11412 /* create IndexBuffer*/
11413 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11414 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11415 if(!ib) {
11416 skip("Failed to create an index buffer\n");
11417 goto out;
11420 /* copy all Buffers (Vertex + Index)*/
11421 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11422 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11423 memcpy(data, quad, sizeof(quad));
11424 hr = IDirect3DVertexBuffer9_Unlock(vb);
11425 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11426 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11427 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11428 memcpy(data, vertcolor, sizeof(vertcolor));
11429 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11430 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11431 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11432 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11433 memcpy(data, instancepos, sizeof(instancepos));
11434 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11435 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11436 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11437 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11438 memcpy(data, indices, sizeof(indices));
11439 hr = IDirect3DIndexBuffer9_Unlock(ib);
11440 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11442 /* create VertexShader */
11443 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11444 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11445 if(!shader) {
11446 skip("Failed to create a vetex shader\n");
11447 goto out;
11450 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11451 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11453 hr = IDirect3DDevice9_SetIndices(device, ib);
11454 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11456 /* run all tests */
11457 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11459 struct testdata act = testcases[i];
11460 decl[0].Stream = act.strVertex;
11461 decl[1].Stream = act.strColor;
11462 decl[2].Stream = act.strInstance;
11463 /* create VertexDeclarations */
11464 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11465 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11468 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11470 hr = IDirect3DDevice9_BeginScene(device);
11471 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11473 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11474 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11476 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11477 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11478 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11479 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11480 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11482 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11483 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11484 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11485 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11486 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11488 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11489 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11490 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11491 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11492 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11494 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11495 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11496 hr = IDirect3DDevice9_EndScene(device);
11497 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11499 /* set all StreamSource && StreamSourceFreq back to default */
11500 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11501 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11502 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11503 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11504 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11505 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11506 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11507 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11508 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11509 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11510 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11511 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11513 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11514 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11516 color = getPixelColor(device, 160, 360);
11517 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11518 color = getPixelColor(device, 480, 360);
11519 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11520 color = getPixelColor(device, 480, 120);
11521 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11522 color = getPixelColor(device, 160, 120);
11523 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11525 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11526 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11529 out:
11530 if(vb) IDirect3DVertexBuffer9_Release(vb);
11531 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11532 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11533 if(ib)IDirect3DIndexBuffer9_Release(ib);
11534 if(shader)IDirect3DVertexShader9_Release(shader);
11535 refcount = IDirect3DDevice9_Release(device);
11536 ok(!refcount, "Device has %u references left.\n", refcount);
11537 done:
11538 IDirect3D9_Release(d3d);
11539 DestroyWindow(window);
11542 static void np2_stretch_rect_test(void)
11544 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11545 IDirect3DTexture9 *dsttex = NULL;
11546 IDirect3DDevice9 *device;
11547 IDirect3D9 *d3d;
11548 D3DCOLOR color;
11549 ULONG refcount;
11550 HWND window;
11551 HRESULT hr;
11553 static const D3DRECT r1 = {0, 0, 50, 50 };
11554 static const D3DRECT r2 = {50, 0, 100, 50 };
11555 static const D3DRECT r3 = {50, 50, 100, 100};
11556 static const D3DRECT r4 = {0, 50, 50, 100};
11557 static const float quad[] =
11559 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11560 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11561 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11562 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11565 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11566 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11567 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11568 ok(!!d3d, "Failed to create a D3D object.\n");
11569 if (!(device = create_device(d3d, window, window, TRUE)))
11571 skip("Failed to create a D3D device, skipping tests.\n");
11572 goto done;
11575 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11576 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11578 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11579 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11580 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11581 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11583 if(!src || !dsttex) {
11584 skip("One or more test resources could not be created\n");
11585 goto cleanup;
11588 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11589 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11591 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11592 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11594 /* Clear the StretchRect destination for debugging */
11595 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11596 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11598 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11600 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11601 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11603 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11604 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11605 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11606 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11607 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11608 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11609 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11610 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11612 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11613 * the target -> texture GL blit path
11615 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11616 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11617 IDirect3DSurface9_Release(dst);
11619 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11622 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11623 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11624 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11625 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11626 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11627 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11628 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11629 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11631 hr = IDirect3DDevice9_BeginScene(device);
11632 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11634 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11635 hr = IDirect3DDevice9_EndScene(device);
11636 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11638 color = getPixelColor(device, 160, 360);
11639 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11640 color = getPixelColor(device, 480, 360);
11641 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11642 color = getPixelColor(device, 480, 120);
11643 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11644 color = getPixelColor(device, 160, 120);
11645 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11646 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11647 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11649 cleanup:
11650 if(src) IDirect3DSurface9_Release(src);
11651 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11652 if(dsttex) IDirect3DTexture9_Release(dsttex);
11653 refcount = IDirect3DDevice9_Release(device);
11654 ok(!refcount, "Device has %u references left.\n", refcount);
11655 done:
11656 IDirect3D9_Release(d3d);
11657 DestroyWindow(window);
11660 static void texop_test(void)
11662 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11663 IDirect3DTexture9 *texture = NULL;
11664 D3DLOCKED_RECT locked_rect;
11665 IDirect3DDevice9 *device;
11666 IDirect3D9 *d3d;
11667 D3DCOLOR color;
11668 ULONG refcount;
11669 D3DCAPS9 caps;
11670 HWND window;
11671 HRESULT hr;
11672 unsigned i;
11674 static const struct {
11675 float x, y, z;
11676 float s, t;
11677 D3DCOLOR diffuse;
11678 } quad[] = {
11679 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11680 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11681 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11682 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11685 static const D3DVERTEXELEMENT9 decl_elements[] = {
11686 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11687 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11688 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11689 D3DDECL_END()
11692 static const struct {
11693 D3DTEXTUREOP op;
11694 const char *name;
11695 DWORD caps_flag;
11696 D3DCOLOR result;
11697 } test_data[] = {
11698 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11699 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
11700 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
11701 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
11702 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11703 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11704 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
11705 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11706 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11707 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11708 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11709 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
11710 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
11711 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11712 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11713 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
11714 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
11715 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11716 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
11717 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
11718 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
11719 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
11720 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
11723 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11724 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11725 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11726 ok(!!d3d, "Failed to create a D3D object.\n");
11727 if (!(device = create_device(d3d, window, window, TRUE)))
11729 skip("Failed to create a D3D device, skipping tests.\n");
11730 goto done;
11733 memset(&caps, 0, sizeof(caps));
11734 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11735 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11737 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11738 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
11739 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
11740 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
11742 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11743 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11744 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11745 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11746 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
11747 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11748 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11749 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11750 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11752 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
11753 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11754 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11755 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11756 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11757 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11759 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
11760 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11762 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11763 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
11765 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
11767 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11769 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11770 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11772 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
11774 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
11776 skip("tex operation %s not supported\n", test_data[i].name);
11777 continue;
11780 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
11781 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
11783 hr = IDirect3DDevice9_BeginScene(device);
11784 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11787 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11789 hr = IDirect3DDevice9_EndScene(device);
11790 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11792 color = getPixelColor(device, 320, 240);
11793 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
11794 test_data[i].name, color, test_data[i].result);
11796 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11797 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11800 IDirect3DTexture9_Release(texture);
11801 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11802 refcount = IDirect3DDevice9_Release(device);
11803 ok(!refcount, "Device has %u references left.\n", refcount);
11804 done:
11805 IDirect3D9_Release(d3d);
11806 DestroyWindow(window);
11809 static void yuv_color_test(void)
11811 HRESULT hr;
11812 IDirect3DSurface9 *surface, *target;
11813 unsigned int i;
11814 D3DLOCKED_RECT lr;
11815 IDirect3D9 *d3d;
11816 D3DCOLOR color;
11817 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
11818 IDirect3DDevice9 *device;
11819 D3DSURFACE_DESC desc;
11820 ULONG refcount;
11821 HWND window;
11823 static const struct
11825 DWORD in;
11826 D3DFORMAT format;
11827 const char *fmt_string;
11828 D3DCOLOR left, right;
11830 test_data[] =
11832 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
11833 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
11834 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
11835 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
11836 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
11837 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
11838 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
11839 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
11840 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
11841 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
11842 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
11843 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
11844 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
11845 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
11846 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
11847 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
11848 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
11849 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
11851 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
11852 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
11853 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
11854 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
11855 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
11856 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
11857 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
11858 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
11859 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
11860 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
11861 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
11862 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
11863 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
11864 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
11865 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
11866 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
11867 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
11868 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
11871 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11872 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11873 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11874 ok(!!d3d, "Failed to create a D3D object.\n");
11875 if (!(device = create_device(d3d, window, window, TRUE)))
11877 skip("Failed to create a D3D device, skipping tests.\n");
11878 goto done;
11881 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11882 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
11883 hr = IDirect3DSurface9_GetDesc(target, &desc);
11884 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11886 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11888 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
11889 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
11890 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11891 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
11893 if (skip_once != test_data[i].format)
11895 skip("%s is not supported.\n", test_data[i].fmt_string);
11896 skip_once = test_data[i].format;
11898 continue;
11900 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11901 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
11903 if (skip_once != test_data[i].format)
11905 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
11906 skip_once = test_data[i].format;
11908 continue;
11911 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
11912 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
11913 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
11914 * second luminance value, resulting in an incorrect color in the right pixel. */
11915 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
11916 D3DPOOL_DEFAULT, &surface, NULL);
11917 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
11920 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11921 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
11922 ((DWORD *)lr.pBits)[0] = test_data[i].in;
11923 ((DWORD *)lr.pBits)[1] = 0x00800080;
11924 hr = IDirect3DSurface9_UnlockRect(surface);
11925 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
11927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11928 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11929 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11930 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
11932 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11933 * although we asked for point filtering. Be careful when reading the results and use the pixel
11934 * centers. In the future we may want to add tests for the filtered pixels as well.
11936 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11937 * vastly differently, so we need a max diff of 18. */
11938 color = getPixelColor(device, 1, 240);
11939 ok(color_match(color, test_data[i].left, 18),
11940 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
11941 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
11942 color = getPixelColor(device, 318, 240);
11943 ok(color_match(color, test_data[i].right, 18),
11944 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
11945 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
11946 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11947 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11948 IDirect3DSurface9_Release(surface);
11951 IDirect3DSurface9_Release(target);
11952 refcount = IDirect3DDevice9_Release(device);
11953 ok(!refcount, "Device has %u references left.\n", refcount);
11954 done:
11955 IDirect3D9_Release(d3d);
11956 DestroyWindow(window);
11959 static void yuv_layout_test(void)
11961 HRESULT hr;
11962 IDirect3DSurface9 *surface, *target;
11963 unsigned int fmt, i, x, y;
11964 D3DFORMAT format;
11965 const char *fmt_string;
11966 D3DLOCKED_RECT lr;
11967 IDirect3D9 *d3d;
11968 D3DCOLOR color;
11969 DWORD ref_color;
11970 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
11971 UINT width = 20, height = 16;
11972 IDirect3DDevice9 *device;
11973 ULONG refcount;
11974 D3DCAPS9 caps;
11975 D3DSURFACE_DESC desc;
11976 HWND window;
11978 static const struct
11980 DWORD color1, color2;
11981 DWORD rgb1, rgb2;
11983 test_data[] =
11985 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
11986 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
11987 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
11988 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
11989 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
11990 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
11991 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
11992 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
11995 static const struct
11997 D3DFORMAT format;
11998 const char *str;
12000 formats[] =
12002 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12003 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12004 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12005 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12008 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12009 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12010 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12011 ok(!!d3d, "Failed to create a D3D object.\n");
12012 if (!(device = create_device(d3d, window, window, TRUE)))
12014 skip("Failed to create a D3D device, skipping tests.\n");
12015 goto done;
12018 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12019 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12020 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12021 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12023 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12024 IDirect3DDevice9_Release(device);
12025 goto done;
12028 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12029 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12030 hr = IDirect3DSurface9_GetDesc(target, &desc);
12031 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12033 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12035 format = formats[fmt].format;
12036 fmt_string = formats[fmt].str;
12038 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12039 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12040 * of drawPrimitive. */
12041 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12042 D3DRTYPE_SURFACE, format) != D3D_OK)
12044 skip("%s is not supported.\n", fmt_string);
12045 continue;
12047 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12048 D3DDEVTYPE_HAL, format, desc.Format)))
12050 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12051 continue;
12054 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12055 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12057 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12059 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12060 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12061 buf = lr.pBits;
12062 chroma_buf = buf + lr.Pitch * height;
12063 if (format == MAKEFOURCC('Y','V','1','2'))
12065 v_buf = chroma_buf;
12066 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12068 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12069 for (y = 0; y < height; y++)
12071 for (x = 0; x < width; x += 2)
12073 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12074 BYTE Y = (color >> 16) & 0xff;
12075 BYTE U = (color >> 8) & 0xff;
12076 BYTE V = (color >> 0) & 0xff;
12077 if (format == D3DFMT_UYVY)
12079 buf[y * lr.Pitch + 2 * x + 0] = U;
12080 buf[y * lr.Pitch + 2 * x + 1] = Y;
12081 buf[y * lr.Pitch + 2 * x + 2] = V;
12082 buf[y * lr.Pitch + 2 * x + 3] = Y;
12084 else if (format == D3DFMT_YUY2)
12086 buf[y * lr.Pitch + 2 * x + 0] = Y;
12087 buf[y * lr.Pitch + 2 * x + 1] = U;
12088 buf[y * lr.Pitch + 2 * x + 2] = Y;
12089 buf[y * lr.Pitch + 2 * x + 3] = V;
12091 else if (format == MAKEFOURCC('Y','V','1','2'))
12093 buf[y * lr.Pitch + x + 0] = Y;
12094 buf[y * lr.Pitch + x + 1] = Y;
12095 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12096 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12098 else if (format == MAKEFOURCC('N','V','1','2'))
12100 buf[y * lr.Pitch + x + 0] = Y;
12101 buf[y * lr.Pitch + x + 1] = Y;
12102 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12103 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12107 hr = IDirect3DSurface9_UnlockRect(surface);
12108 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12111 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12112 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12113 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12115 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12116 * although we asked for point filtering. To prevent running into precision problems, read at points
12117 * with some margin within each quadrant.
12119 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12120 * vastly differently, so we need a max diff of 18. */
12121 for (y = 0; y < 4; y++)
12123 for (x = 0; x < 4; x++)
12125 UINT xcoord = (1 + 2 * x) * 640 / 8;
12126 UINT ycoord = (1 + 2 * y) * 480 / 8;
12127 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12128 color = getPixelColor(device, xcoord, ycoord);
12129 ok(color_match(color, ref_color, 18),
12130 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12131 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12134 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12136 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12138 IDirect3DSurface9_Release(surface);
12141 IDirect3DSurface9_Release(target);
12142 refcount = IDirect3DDevice9_Release(device);
12143 ok(!refcount, "Device has %u references left.\n", refcount);
12144 done:
12145 IDirect3D9_Release(d3d);
12146 DestroyWindow(window);
12149 static void texop_range_test(void)
12151 IDirect3DTexture9 *texture;
12152 D3DLOCKED_RECT locked_rect;
12153 IDirect3DDevice9 *device;
12154 IDirect3D9 *d3d;
12155 ULONG refcount;
12156 D3DCAPS9 caps;
12157 DWORD color;
12158 HWND window;
12159 HRESULT hr;
12161 static const struct
12163 float x, y, z;
12164 D3DCOLOR diffuse;
12166 quad[] =
12168 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12169 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12170 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12171 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12174 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12175 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12176 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12177 ok(!!d3d, "Failed to create a D3D object.\n");
12178 if (!(device = create_device(d3d, window, window, TRUE)))
12180 skip("Failed to create a D3D device, skipping tests.\n");
12181 goto done;
12184 /* We need ADD and SUBTRACT operations */
12185 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12186 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12187 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12189 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12190 IDirect3DDevice9_Release(device);
12191 goto done;
12193 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12195 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12196 IDirect3DDevice9_Release(device);
12197 goto done;
12200 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12201 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12203 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12204 /* Stage 1: result = diffuse(=1.0) + diffuse
12205 * stage 2: result = result - tfactor(= 0.5)
12207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12208 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12209 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12210 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12211 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12212 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12213 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12214 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12215 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12216 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12217 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12218 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12219 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12220 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12222 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12223 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12224 hr = IDirect3DDevice9_BeginScene(device);
12225 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12227 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12228 hr = IDirect3DDevice9_EndScene(device);
12229 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12231 color = getPixelColor(device, 320, 240);
12232 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12233 color);
12234 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12235 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12237 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12238 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12239 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12240 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12241 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12242 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12243 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12244 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12245 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12247 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12248 * stage 2: result = result + diffuse(1.0)
12250 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12251 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12252 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12253 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12254 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12255 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12256 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12257 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12258 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12259 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12260 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12261 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12262 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12263 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12265 hr = IDirect3DDevice9_BeginScene(device);
12266 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12268 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12269 hr = IDirect3DDevice9_EndScene(device);
12270 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12272 color = getPixelColor(device, 320, 240);
12273 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12274 color);
12275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12276 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12278 IDirect3DTexture9_Release(texture);
12279 refcount = IDirect3DDevice9_Release(device);
12280 ok(!refcount, "Device has %u references left.\n", refcount);
12281 done:
12282 IDirect3D9_Release(d3d);
12283 DestroyWindow(window);
12286 static void alphareplicate_test(void)
12288 IDirect3DDevice9 *device;
12289 IDirect3D9 *d3d;
12290 ULONG refcount;
12291 DWORD color;
12292 HWND window;
12293 HRESULT hr;
12295 static const struct
12297 struct vec3 position;
12298 DWORD diffuse;
12300 quad[] =
12302 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12303 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12304 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12305 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12308 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12309 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12310 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12311 ok(!!d3d, "Failed to create a D3D object.\n");
12312 if (!(device = create_device(d3d, window, window, TRUE)))
12314 skip("Failed to create a D3D device, skipping tests.\n");
12315 goto done;
12318 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12319 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12321 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12322 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12324 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12325 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12326 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12327 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12329 hr = IDirect3DDevice9_BeginScene(device);
12330 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12332 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12333 hr = IDirect3DDevice9_EndScene(device);
12334 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12336 color = getPixelColor(device, 320, 240);
12337 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12338 color);
12339 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12340 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12342 refcount = IDirect3DDevice9_Release(device);
12343 ok(!refcount, "Device has %u references left.\n", refcount);
12344 done:
12345 IDirect3D9_Release(d3d);
12346 DestroyWindow(window);
12349 static void dp3_alpha_test(void)
12351 IDirect3DDevice9 *device;
12352 IDirect3D9 *d3d;
12353 ULONG refcount;
12354 D3DCAPS9 caps;
12355 DWORD color;
12356 HWND window;
12357 HRESULT hr;
12359 static const struct
12361 struct vec3 position;
12362 DWORD diffuse;
12364 quad[] =
12366 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12367 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12368 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12369 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12372 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12373 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12374 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12375 ok(!!d3d, "Failed to create a D3D object.\n");
12376 if (!(device = create_device(d3d, window, window, TRUE)))
12378 skip("Failed to create a D3D device, skipping tests.\n");
12379 goto done;
12382 memset(&caps, 0, sizeof(caps));
12383 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12384 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12385 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12387 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12388 IDirect3DDevice9_Release(device);
12389 goto done;
12392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 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);
12398 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12399 * mov r0.a, diffuse.a
12400 * mov r0, r0.a
12402 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12403 * 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
12404 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12406 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12407 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12408 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12410 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12411 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12412 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12413 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12414 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12416 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12418 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12420 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12421 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12423 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12425 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12427 hr = IDirect3DDevice9_BeginScene(device);
12428 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12430 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12431 hr = IDirect3DDevice9_EndScene(device);
12432 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12434 color = getPixelColor(device, 320, 240);
12435 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12436 color);
12437 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12438 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12440 refcount = IDirect3DDevice9_Release(device);
12441 ok(!refcount, "Device has %u references left.\n", refcount);
12442 done:
12443 IDirect3D9_Release(d3d);
12444 DestroyWindow(window);
12447 static void zwriteenable_test(void)
12449 IDirect3DDevice9 *device;
12450 IDirect3D9 *d3d;
12451 D3DCOLOR color;
12452 ULONG refcount;
12453 HWND window;
12454 HRESULT hr;
12456 static const struct
12458 struct vec3 position;
12459 DWORD diffuse;
12461 quad1[] =
12463 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12464 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12465 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12466 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12468 quad2[] =
12470 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12471 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12472 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12473 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12476 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12477 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12478 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12479 ok(!!d3d, "Failed to create a D3D object.\n");
12480 if (!(device = create_device(d3d, window, window, TRUE)))
12482 skip("Failed to create a D3D device, skipping tests.\n");
12483 goto done;
12486 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12487 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12490 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12491 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12492 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12493 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12494 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12495 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12496 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12498 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12500 hr = IDirect3DDevice9_BeginScene(device);
12501 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12502 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12503 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12504 * because the z test is disabled. The question is whether the z = 0.1
12505 * values are written into the Z buffer. After the draw, set
12506 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12507 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12508 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12509 * green color is written. It turns out that the screen is green, so
12510 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12511 * buffer. */
12512 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12513 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12515 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12516 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12517 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12518 hr = IDirect3DDevice9_EndScene(device);
12519 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12521 color = getPixelColor(device, 320, 240);
12522 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12523 color);
12524 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12525 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12527 refcount = IDirect3DDevice9_Release(device);
12528 ok(!refcount, "Device has %u references left.\n", refcount);
12529 done:
12530 IDirect3D9_Release(d3d);
12531 DestroyWindow(window);
12534 static void alphatest_test(void)
12536 #define ALPHATEST_PASSED 0x0000ff00
12537 #define ALPHATEST_FAILED 0x00ff0000
12538 IDirect3DDevice9 *device;
12539 unsigned int i, j;
12540 IDirect3D9 *d3d;
12541 D3DCOLOR color;
12542 ULONG refcount;
12543 D3DCAPS9 caps;
12544 HWND window;
12545 HRESULT hr;
12547 static const struct
12549 D3DCMPFUNC func;
12550 D3DCOLOR color_less;
12551 D3DCOLOR color_equal;
12552 D3DCOLOR color_greater;
12554 testdata[] =
12556 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12557 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12558 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12559 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12560 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12561 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12562 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12563 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12565 static const struct
12567 struct vec3 position;
12568 DWORD diffuse;
12570 quad[] =
12572 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12573 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12574 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12575 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12578 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12579 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12580 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12581 ok(!!d3d, "Failed to create a D3D object.\n");
12582 if (!(device = create_device(d3d, window, window, TRUE)))
12584 skip("Failed to create a D3D device, skipping tests.\n");
12585 goto done;
12588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12589 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12592 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12595 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12596 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12598 for (j = 0; j < 2; ++j)
12600 if (j == 1)
12602 /* Try a pixel shader instead of fixed function. The wined3d code
12603 * may emulate the alpha test either for performance reasons
12604 * (floating point RTs) or to work around driver bugs (GeForce
12605 * 7x00 cards on MacOS). There may be a different codepath for ffp
12606 * and shader in this case, and the test should cover both. */
12607 IDirect3DPixelShader9 *ps;
12608 static const DWORD shader_code[] =
12610 0xffff0101, /* ps_1_1 */
12611 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12612 0x0000ffff /* end */
12614 memset(&caps, 0, sizeof(caps));
12615 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12616 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12617 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12618 break;
12621 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12622 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12623 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12624 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12625 IDirect3DPixelShader9_Release(ps);
12628 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12630 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12632 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12633 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12635 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12636 hr = IDirect3DDevice9_BeginScene(device);
12637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12639 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12640 hr = IDirect3DDevice9_EndScene(device);
12641 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12642 color = getPixelColor(device, 320, 240);
12643 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12644 color, testdata[i].color_less, testdata[i].func);
12645 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12646 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12649 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12651 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12652 hr = IDirect3DDevice9_BeginScene(device);
12653 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12655 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12656 hr = IDirect3DDevice9_EndScene(device);
12657 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12658 color = getPixelColor(device, 320, 240);
12659 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12660 color, testdata[i].color_equal, testdata[i].func);
12661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12662 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12664 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12665 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12668 hr = IDirect3DDevice9_BeginScene(device);
12669 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12671 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12672 hr = IDirect3DDevice9_EndScene(device);
12673 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12674 color = getPixelColor(device, 320, 240);
12675 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12676 color, testdata[i].color_greater, testdata[i].func);
12677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12678 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12682 refcount = IDirect3DDevice9_Release(device);
12683 ok(!refcount, "Device has %u references left.\n", refcount);
12684 done:
12685 IDirect3D9_Release(d3d);
12686 DestroyWindow(window);
12689 static void sincos_test(void)
12691 IDirect3DVertexShader9 *sin_shader, *cos_shader;
12692 IDirect3DDevice9 *device;
12693 struct vec3 data[1280];
12694 IDirect3D9 *d3d;
12695 unsigned int i;
12696 ULONG refcount;
12697 D3DCAPS9 caps;
12698 HWND window;
12699 HRESULT hr;
12701 static const DWORD sin_shader_code[] =
12703 0xfffe0200, /* vs_2_0 */
12704 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12705 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12706 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12707 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
12708 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12709 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
12710 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
12711 0x0000ffff /* end */
12713 static const DWORD cos_shader_code[] =
12715 0xfffe0200, /* vs_2_0 */
12716 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12717 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12718 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12719 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
12720 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12721 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
12722 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
12723 0x0000ffff /* end */
12725 static const float sincosc1[4] = {D3DSINCOSCONST1};
12726 static const float sincosc2[4] = {D3DSINCOSCONST2};
12728 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12729 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12730 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12731 ok(!!d3d, "Failed to create a D3D object.\n");
12732 if (!(device = create_device(d3d, window, window, TRUE)))
12734 skip("Failed to create a D3D device, skipping tests.\n");
12735 goto done;
12738 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12739 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12740 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12742 skip("No vs_2_0 support, skipping tests.\n");
12743 IDirect3DDevice9_Release(device);
12744 goto done;
12747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12748 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12750 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
12751 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12752 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
12753 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12754 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12755 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12756 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
12757 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12758 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
12759 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12761 /* Generate a point from -1 to 1 every 0.5 pixels */
12762 for(i = 0; i < 1280; i++) {
12763 data[i].x = (-640.0 + i) / 640.0;
12764 data[i].y = 0.0;
12765 data[i].z = 0.1;
12768 hr = IDirect3DDevice9_BeginScene(device);
12769 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12771 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
12772 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
12773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12774 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12776 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
12777 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
12778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12779 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12781 hr = IDirect3DDevice9_EndScene(device);
12782 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12784 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12785 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
12786 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
12788 IDirect3DVertexShader9_Release(sin_shader);
12789 IDirect3DVertexShader9_Release(cos_shader);
12790 refcount = IDirect3DDevice9_Release(device);
12791 ok(!refcount, "Device has %u references left.\n", refcount);
12792 done:
12793 IDirect3D9_Release(d3d);
12794 DestroyWindow(window);
12797 static void loop_index_test(void)
12799 IDirect3DVertexShader9 *shader;
12800 IDirect3DDevice9 *device;
12801 IDirect3D9 *d3d;
12802 float values[4];
12803 ULONG refcount;
12804 D3DCAPS9 caps;
12805 DWORD color;
12806 HWND window;
12807 HRESULT hr;
12809 static const DWORD shader_code[] =
12811 0xfffe0200, /* vs_2_0 */
12812 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12813 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
12814 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
12815 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
12816 0x0000001d, /* endloop */
12817 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12818 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
12819 0x0000ffff /* END */
12821 static const float quad[] =
12823 -1.0f, -1.0f, 0.1f,
12824 -1.0f, 1.0f, 0.1f,
12825 1.0f, -1.0f, 0.1f,
12826 1.0f, 1.0f, 0.1f,
12828 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
12829 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
12830 static const int i0[4] = {2, 10, -3, 0};
12832 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12833 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12834 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12835 ok(!!d3d, "Failed to create a D3D object.\n");
12836 if (!(device = create_device(d3d, window, window, TRUE)))
12838 skip("Failed to create a D3D device, skipping tests.\n");
12839 goto done;
12842 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12843 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12844 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12846 skip("No vs_2_0 support, skipping tests.\n");
12847 IDirect3DDevice9_Release(device);
12848 goto done;
12851 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12852 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12853 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12854 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12855 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12856 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12858 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12860 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
12861 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12862 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
12863 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12864 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
12865 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12866 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
12867 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12868 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
12869 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12870 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
12871 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12872 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
12873 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12874 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
12875 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12876 values[0] = 1.0;
12877 values[1] = 1.0;
12878 values[2] = 0.0;
12879 values[3] = 0.0;
12880 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
12881 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12882 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
12883 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12884 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
12885 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12886 values[0] = -1.0;
12887 values[1] = 0.0;
12888 values[2] = 0.0;
12889 values[3] = 0.0;
12890 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
12891 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12892 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
12893 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12894 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
12895 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12896 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
12897 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12898 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
12899 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12901 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
12902 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
12904 hr = IDirect3DDevice9_BeginScene(device);
12905 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12907 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12908 hr = IDirect3DDevice9_EndScene(device);
12909 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12910 color = getPixelColor(device, 320, 240);
12911 ok(color_match(color, 0x0000ff00, 1),
12912 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
12913 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12914 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12916 IDirect3DVertexShader9_Release(shader);
12917 refcount = IDirect3DDevice9_Release(device);
12918 ok(!refcount, "Device has %u references left.\n", refcount);
12919 done:
12920 IDirect3D9_Release(d3d);
12921 DestroyWindow(window);
12924 static void sgn_test(void)
12926 IDirect3DVertexShader9 *shader;
12927 IDirect3DDevice9 *device;
12928 IDirect3D9 *d3d;
12929 ULONG refcount;
12930 D3DCAPS9 caps;
12931 DWORD color;
12932 HWND window;
12933 HRESULT hr;
12935 static const DWORD shader_code[] =
12937 0xfffe0200, /* vs_2_0 */
12938 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
12939 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
12940 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
12941 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12942 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
12943 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
12944 0x0000ffff /* end */
12946 static const float quad[] =
12948 -1.0f, -1.0f, 0.1f,
12949 -1.0f, 1.0f, 0.1f,
12950 1.0f, -1.0f, 0.1f,
12951 1.0f, 1.0f, 0.1f,
12954 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12955 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12956 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12957 ok(!!d3d, "Failed to create a D3D object.\n");
12958 if (!(device = create_device(d3d, window, window, TRUE)))
12960 skip("Failed to create a D3D device, skipping tests.\n");
12961 goto done;
12964 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12965 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12966 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12968 skip("No vs_2_0 support, skipping tests.\n");
12969 IDirect3DDevice9_Release(device);
12970 goto done;
12973 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12974 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12975 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12976 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12977 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12978 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12979 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12980 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12982 hr = IDirect3DDevice9_BeginScene(device);
12983 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12985 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12986 hr = IDirect3DDevice9_EndScene(device);
12987 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12988 color = getPixelColor(device, 320, 240);
12989 ok(color_match(color, 0x008000ff, 1),
12990 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
12991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12992 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12994 IDirect3DVertexShader9_Release(shader);
12995 refcount = IDirect3DDevice9_Release(device);
12996 ok(!refcount, "Device has %u references left.\n", refcount);
12997 done:
12998 IDirect3D9_Release(d3d);
12999 DestroyWindow(window);
13002 static void viewport_test(void)
13004 IDirect3DDevice9 *device;
13005 BOOL draw_failed = TRUE;
13006 D3DVIEWPORT9 vp;
13007 IDirect3D9 *d3d;
13008 ULONG refcount;
13009 DWORD color;
13010 HWND window;
13011 HRESULT hr;
13013 static const float quad[] =
13015 -0.5f, -0.5f, 0.1f,
13016 -0.5f, 0.5f, 0.1f,
13017 0.5f, -0.5f, 0.1f,
13018 0.5f, 0.5f, 0.1f,
13021 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13022 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13023 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13024 ok(!!d3d, "Failed to create a D3D object.\n");
13025 if (!(device = create_device(d3d, window, window, TRUE)))
13027 skip("Failed to create a D3D device, skipping tests.\n");
13028 goto done;
13031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13034 /* Test a viewport with Width and Height bigger than the surface dimensions
13036 * TODO: Test Width < surface.width, but X + Width > surface.width
13037 * TODO: Test Width < surface.width, what happens with the height?
13039 * The expected behavior is that the viewport behaves like the "default"
13040 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13041 * MinZ = 0.0, MaxZ = 1.0.
13043 * Starting with Windows 7 the behavior among driver versions is not
13044 * consistent. The SetViewport call is accepted on all drivers. Some
13045 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13046 * nvidia drivers draw, but use the actual values in the viewport and only
13047 * display the upper left part on the surface.
13049 memset(&vp, 0, sizeof(vp));
13050 vp.X = 0;
13051 vp.Y = 0;
13052 vp.Width = 10000;
13053 vp.Height = 10000;
13054 vp.MinZ = 0.0;
13055 vp.MaxZ = 0.0;
13056 hr = IDirect3DDevice9_SetViewport(device, &vp);
13057 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13060 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13062 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13063 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13064 hr = IDirect3DDevice9_BeginScene(device);
13065 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13067 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13068 draw_failed = FAILED(hr);
13069 hr = IDirect3DDevice9_EndScene(device);
13070 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13072 if(!draw_failed)
13074 color = getPixelColor(device, 158, 118);
13075 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13076 color = getPixelColor(device, 162, 118);
13077 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13078 color = getPixelColor(device, 158, 122);
13079 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13080 color = getPixelColor(device, 162, 122);
13081 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13083 color = getPixelColor(device, 478, 358);
13084 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13085 color = getPixelColor(device, 482, 358);
13086 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13087 color = getPixelColor(device, 478, 362);
13088 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13089 color = getPixelColor(device, 482, 362);
13090 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13094 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13096 refcount = IDirect3DDevice9_Release(device);
13097 ok(!refcount, "Device has %u references left.\n", refcount);
13098 done:
13099 IDirect3D9_Release(d3d);
13100 DestroyWindow(window);
13103 /* This test tests depth clamping / clipping behaviour:
13104 * - With software vertex processing, depth values are clamped to the
13105 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13106 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13107 * same as regular vertices here.
13108 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13109 * Normal vertices are always clipped. Pretransformed vertices are
13110 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13111 * - The viewport's MinZ/MaxZ is irrelevant for this.
13113 static void depth_clamp_test(void)
13115 IDirect3DDevice9 *device;
13116 D3DVIEWPORT9 vp;
13117 IDirect3D9 *d3d;
13118 D3DCOLOR color;
13119 ULONG refcount;
13120 D3DCAPS9 caps;
13121 HWND window;
13122 HRESULT hr;
13124 static const struct
13126 struct vec4 position;
13127 DWORD diffuse;
13129 quad1[] =
13131 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13132 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13133 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13134 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13136 quad2[] =
13138 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13139 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13140 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13141 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13143 quad3[] =
13145 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13146 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13147 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13148 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13150 quad4[] =
13152 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13153 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13154 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13155 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13157 static const struct
13159 struct vec3 position;
13160 DWORD diffuse;
13162 quad5[] =
13164 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13165 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13166 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13167 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13169 quad6[] =
13171 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13172 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13173 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13174 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13177 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13178 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13179 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13180 ok(!!d3d, "Failed to create a D3D object.\n");
13181 if (!(device = create_device(d3d, window, window, TRUE)))
13183 skip("Failed to create a D3D device, skipping tests.\n");
13184 goto done;
13187 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13188 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13190 vp.X = 0;
13191 vp.Y = 0;
13192 vp.Width = 640;
13193 vp.Height = 480;
13194 vp.MinZ = 0.0;
13195 vp.MaxZ = 7.5;
13197 hr = IDirect3DDevice9_SetViewport(device, &vp);
13198 if(FAILED(hr))
13200 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13201 * the tests because the 7.5 is just intended to show that it doesn't have
13202 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13203 * viewport and continue.
13205 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13206 vp.MaxZ = 1.0;
13207 hr = IDirect3DDevice9_SetViewport(device, &vp);
13209 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13212 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13215 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13217 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13219 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13221 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13223 hr = IDirect3DDevice9_BeginScene(device);
13224 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13226 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13227 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13230 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13232 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13238 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13240 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13243 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13245 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13246 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13249 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13252 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13254 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13255 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13257 hr = IDirect3DDevice9_EndScene(device);
13258 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13260 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13262 color = getPixelColor(device, 75, 75);
13263 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13264 color = getPixelColor(device, 150, 150);
13265 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13266 color = getPixelColor(device, 320, 240);
13267 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13268 color = getPixelColor(device, 320, 330);
13269 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13270 color = getPixelColor(device, 320, 330);
13271 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13273 else
13275 color = getPixelColor(device, 75, 75);
13276 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13277 color = getPixelColor(device, 150, 150);
13278 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13279 color = getPixelColor(device, 320, 240);
13280 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13281 color = getPixelColor(device, 320, 330);
13282 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13283 color = getPixelColor(device, 320, 330);
13284 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13287 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13288 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13290 refcount = IDirect3DDevice9_Release(device);
13291 ok(!refcount, "Device has %u references left.\n", refcount);
13292 done:
13293 IDirect3D9_Release(d3d);
13294 DestroyWindow(window);
13297 static void depth_bounds_test(void)
13299 static const struct
13301 struct vec4 position;
13302 DWORD diffuse;
13304 quad1[] =
13306 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13307 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13308 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13309 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13311 quad2[] =
13313 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13314 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13315 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13316 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13318 quad3[] =
13320 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13321 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13322 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13323 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13326 union {
13327 DWORD d;
13328 float f;
13329 } tmpvalue;
13331 IDirect3DSurface9 *offscreen_surface = NULL;
13332 IDirect3DDevice9 *device;
13333 IDirect3D9 *d3d;
13334 D3DCOLOR color;
13335 ULONG refcount;
13336 HWND window;
13337 HRESULT hr;
13339 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13340 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13341 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13342 ok(!!d3d, "Failed to create a D3D object.\n");
13343 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13344 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13346 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13347 goto done;
13349 if (!(device = create_device(d3d, window, window, TRUE)))
13351 skip("Failed to create a D3D device, skipping tests.\n");
13352 goto done;
13355 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13356 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13357 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13358 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13361 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13364 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13366 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13368 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13369 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13370 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13373 hr = IDirect3DDevice9_BeginScene(device);
13374 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13376 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13377 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13380 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13383 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13385 tmpvalue.f = 0.625;
13386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13387 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13389 tmpvalue.f = 0.75;
13390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13391 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13394 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13396 tmpvalue.f = 0.75;
13397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13398 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13401 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13404 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13406 hr = IDirect3DDevice9_EndScene(device);
13407 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13409 color = getPixelColor(device, 150, 130);
13410 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13411 color = getPixelColor(device, 150, 200);
13412 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13413 color = getPixelColor(device, 150, 300-5);
13414 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13415 color = getPixelColor(device, 150, 300+5);
13416 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13417 color = getPixelColor(device, 150, 330);
13418 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13419 color = getPixelColor(device, 150, 360-5);
13420 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13421 color = getPixelColor(device, 150, 360+5);
13422 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13424 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13425 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13426 refcount = IDirect3DDevice9_Release(device);
13427 ok(!refcount, "Device has %u references left.\n", refcount);
13428 done:
13429 IDirect3D9_Release(d3d);
13430 DestroyWindow(window);
13433 static void depth_buffer_test(void)
13435 static const struct
13437 struct vec3 position;
13438 DWORD diffuse;
13440 quad1[] =
13442 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13443 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13444 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13445 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13447 quad2[] =
13449 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13450 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13451 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13452 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13454 quad3[] =
13456 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13457 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13458 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13459 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13461 static const DWORD expected_colors[4][4] =
13463 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13464 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13465 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13466 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13469 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13470 IDirect3DDevice9 *device;
13471 unsigned int i, j;
13472 D3DVIEWPORT9 vp;
13473 IDirect3D9 *d3d;
13474 D3DCOLOR color;
13475 ULONG refcount;
13476 HWND window;
13477 HRESULT hr;
13479 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13480 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13481 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13482 ok(!!d3d, "Failed to create a D3D object.\n");
13483 if (!(device = create_device(d3d, window, window, TRUE)))
13485 skip("Failed to create a D3D device, skipping tests.\n");
13486 goto done;
13489 vp.X = 0;
13490 vp.Y = 0;
13491 vp.Width = 640;
13492 vp.Height = 480;
13493 vp.MinZ = 0.0;
13494 vp.MaxZ = 1.0;
13496 hr = IDirect3DDevice9_SetViewport(device, &vp);
13497 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13500 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13502 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13504 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13505 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13506 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13507 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13508 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13510 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13511 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13512 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13513 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13514 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13515 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13516 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13517 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13518 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13519 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13520 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13522 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13523 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13525 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13527 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13528 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13530 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13532 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13533 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13535 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13537 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13538 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13539 hr = IDirect3DDevice9_BeginScene(device);
13540 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13542 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13543 hr = IDirect3DDevice9_EndScene(device);
13544 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13546 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13547 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13550 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13552 hr = IDirect3DDevice9_BeginScene(device);
13553 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13555 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13556 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13557 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13558 hr = IDirect3DDevice9_EndScene(device);
13559 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13561 for (i = 0; i < 4; ++i)
13563 for (j = 0; j < 4; ++j)
13565 unsigned int x = 80 * ((2 * j) + 1);
13566 unsigned int y = 60 * ((2 * i) + 1);
13567 color = getPixelColor(device, x, y);
13568 ok(color_match(color, expected_colors[i][j], 0),
13569 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13573 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13574 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13576 IDirect3DSurface9_Release(backbuffer);
13577 IDirect3DSurface9_Release(rt3);
13578 IDirect3DSurface9_Release(rt2);
13579 IDirect3DSurface9_Release(rt1);
13580 refcount = IDirect3DDevice9_Release(device);
13581 ok(!refcount, "Device has %u references left.\n", refcount);
13582 done:
13583 IDirect3D9_Release(d3d);
13584 DestroyWindow(window);
13587 /* Test that partial depth copies work the way they're supposed to. The clear
13588 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13589 * the following draw should only copy back the part that was modified. */
13590 static void depth_buffer2_test(void)
13592 static const struct
13594 struct vec3 position;
13595 DWORD diffuse;
13597 quad[] =
13599 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13600 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13601 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13602 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13605 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13606 IDirect3DDevice9 *device;
13607 unsigned int i, j;
13608 D3DVIEWPORT9 vp;
13609 IDirect3D9 *d3d;
13610 D3DCOLOR color;
13611 ULONG refcount;
13612 HWND window;
13613 HRESULT hr;
13615 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13616 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13617 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13618 ok(!!d3d, "Failed to create a D3D object.\n");
13619 if (!(device = create_device(d3d, window, window, TRUE)))
13621 skip("Failed to create a D3D device, skipping tests.\n");
13622 goto done;
13625 vp.X = 0;
13626 vp.Y = 0;
13627 vp.Width = 640;
13628 vp.Height = 480;
13629 vp.MinZ = 0.0;
13630 vp.MaxZ = 1.0;
13632 hr = IDirect3DDevice9_SetViewport(device, &vp);
13633 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13636 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13638 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13640 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13642 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13644 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13646 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13647 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13648 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13649 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13650 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13651 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13652 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13653 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13655 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13656 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13657 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13658 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13660 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13661 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13663 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13665 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13666 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13667 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13668 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13670 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13671 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13674 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13676 hr = IDirect3DDevice9_BeginScene(device);
13677 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13679 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13680 hr = IDirect3DDevice9_EndScene(device);
13681 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13683 for (i = 0; i < 4; ++i)
13685 for (j = 0; j < 4; ++j)
13687 unsigned int x = 80 * ((2 * j) + 1);
13688 unsigned int y = 60 * ((2 * i) + 1);
13689 color = getPixelColor(device, x, y);
13690 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
13691 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
13695 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13696 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13698 IDirect3DSurface9_Release(backbuffer);
13699 IDirect3DSurface9_Release(rt2);
13700 IDirect3DSurface9_Release(rt1);
13701 refcount = IDirect3DDevice9_Release(device);
13702 ok(!refcount, "Device has %u references left.\n", refcount);
13703 done:
13704 IDirect3D9_Release(d3d);
13705 DestroyWindow(window);
13708 static void depth_blit_test(void)
13710 static const struct
13712 struct vec3 position;
13713 DWORD diffuse;
13715 quad1[] =
13717 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
13718 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
13719 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
13720 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
13722 quad2[] =
13724 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
13725 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
13726 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
13727 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
13729 static const DWORD expected_colors[4][4] =
13731 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13732 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13733 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13734 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13737 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
13738 IDirect3DDevice9 *device;
13739 RECT src_rect, dst_rect;
13740 unsigned int i, j;
13741 D3DVIEWPORT9 vp;
13742 IDirect3D9 *d3d;
13743 D3DCOLOR color;
13744 ULONG refcount;
13745 HWND window;
13746 HRESULT hr;
13748 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13749 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13750 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13751 ok(!!d3d, "Failed to create a D3D object.\n");
13752 if (!(device = create_device(d3d, window, window, TRUE)))
13754 skip("Failed to create a D3D device, skipping tests.\n");
13755 goto done;
13758 vp.X = 0;
13759 vp.Y = 0;
13760 vp.Width = 640;
13761 vp.Height = 480;
13762 vp.MinZ = 0.0;
13763 vp.MaxZ = 1.0;
13765 hr = IDirect3DDevice9_SetViewport(device, &vp);
13766 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13768 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13769 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13770 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
13771 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13772 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
13773 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13774 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
13775 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13776 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
13777 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13780 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13782 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13784 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13785 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13786 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13788 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13789 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13790 SetRect(&dst_rect, 0, 0, 480, 360);
13791 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
13792 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13793 SetRect(&dst_rect, 0, 0, 320, 240);
13794 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13795 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13797 /* Partial blit. */
13798 SetRect(&src_rect, 0, 0, 320, 240);
13799 SetRect(&dst_rect, 0, 0, 320, 240);
13800 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13801 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13802 /* Flipped. */
13803 SetRect(&src_rect, 0, 0, 640, 480);
13804 SetRect(&dst_rect, 0, 480, 640, 0);
13805 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13806 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13807 /* Full, explicit. */
13808 SetRect(&src_rect, 0, 0, 640, 480);
13809 SetRect(&dst_rect, 0, 0, 640, 480);
13810 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13811 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13812 /* Filtered blit. */
13813 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
13814 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13815 /* Depth -> color blit.*/
13816 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
13817 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13818 IDirect3DSurface9_Release(backbuffer);
13819 /* Full surface, different sizes */
13820 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
13821 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13822 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
13823 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13825 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
13826 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13827 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
13828 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13829 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
13830 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13833 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13834 hr = IDirect3DDevice9_BeginScene(device);
13835 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13837 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13839 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13840 hr = IDirect3DDevice9_EndScene(device);
13841 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13843 for (i = 0; i < 4; ++i)
13845 for (j = 0; j < 4; ++j)
13847 unsigned int x = 80 * ((2 * j) + 1);
13848 unsigned int y = 60 * ((2 * i) + 1);
13849 color = getPixelColor(device, x, y);
13850 ok(color_match(color, expected_colors[i][j], 0),
13851 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13855 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13856 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13858 IDirect3DSurface9_Release(ds3);
13859 IDirect3DSurface9_Release(ds2);
13860 IDirect3DSurface9_Release(ds1);
13861 refcount = IDirect3DDevice9_Release(device);
13862 ok(!refcount, "Device has %u references left.\n", refcount);
13863 done:
13864 IDirect3D9_Release(d3d);
13865 DestroyWindow(window);
13868 static void intz_test(void)
13870 static const DWORD ps_code[] =
13872 0xffff0200, /* ps_2_0 */
13873 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13874 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13875 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13876 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13877 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13878 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13879 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13880 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13881 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13882 0x0000ffff, /* end */
13884 struct
13886 float x, y, z;
13887 float s, t, p, q;
13889 quad[] =
13891 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13892 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13893 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13894 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13896 half_quad_1[] =
13898 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13899 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13900 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13901 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13903 half_quad_2[] =
13905 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13906 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13907 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13908 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13910 struct
13912 UINT x, y;
13913 D3DCOLOR color;
13915 expected_colors[] =
13917 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13918 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13919 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13920 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13921 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13922 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13923 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13924 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13927 IDirect3DSurface9 *original_rt, *rt;
13928 IDirect3DTexture9 *texture;
13929 IDirect3DPixelShader9 *ps;
13930 IDirect3DDevice9 *device;
13931 IDirect3DSurface9 *ds;
13932 IDirect3D9 *d3d;
13933 ULONG refcount;
13934 D3DCAPS9 caps;
13935 HWND window;
13936 HRESULT hr;
13937 UINT i;
13939 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13940 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13941 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13942 ok(!!d3d, "Failed to create a D3D object.\n");
13943 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13944 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
13946 skip("No INTZ support, skipping INTZ test.\n");
13947 goto done;
13949 if (!(device = create_device(d3d, window, window, TRUE)))
13951 skip("Failed to create a D3D device, skipping tests.\n");
13952 goto done;
13955 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13956 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13957 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13959 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13960 IDirect3DDevice9_Release(device);
13961 goto done;
13963 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13965 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13966 IDirect3DDevice9_Release(device);
13967 goto done;
13970 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13971 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13973 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13974 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13975 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13976 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13977 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13978 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13979 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13980 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13982 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13983 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13985 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13987 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13989 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13991 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13993 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13994 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13995 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13996 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13997 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13998 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13999 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14000 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14001 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14002 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14004 /* Render offscreen, using the INTZ texture as depth buffer */
14005 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14006 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14007 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14008 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14009 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14010 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14011 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14012 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14014 /* Setup the depth/stencil surface. */
14015 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14016 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14018 hr = IDirect3DDevice9_BeginScene(device);
14019 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14020 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14021 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14022 hr = IDirect3DDevice9_EndScene(device);
14023 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14025 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14026 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14027 IDirect3DSurface9_Release(ds);
14028 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14029 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14030 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14031 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14032 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14033 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14035 /* Read the depth values back. */
14036 hr = IDirect3DDevice9_BeginScene(device);
14037 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14039 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14040 hr = IDirect3DDevice9_EndScene(device);
14041 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14043 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14045 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14046 ok(color_match(color, expected_colors[i].color, 1),
14047 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14048 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14052 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14054 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14055 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14056 IDirect3DTexture9_Release(texture);
14058 /* Render onscreen while using the INTZ texture as depth buffer */
14059 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14060 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14061 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14062 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14063 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14064 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14065 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14066 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14068 /* Setup the depth/stencil surface. */
14069 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14070 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14072 hr = IDirect3DDevice9_BeginScene(device);
14073 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14075 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14076 hr = IDirect3DDevice9_EndScene(device);
14077 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14079 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14080 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14081 IDirect3DSurface9_Release(ds);
14082 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14083 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14084 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14085 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14087 /* Read the depth values back. */
14088 hr = IDirect3DDevice9_BeginScene(device);
14089 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14091 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14092 hr = IDirect3DDevice9_EndScene(device);
14093 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14095 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14097 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14098 ok(color_match(color, expected_colors[i].color, 1),
14099 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14100 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14103 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14104 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14106 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14107 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14108 IDirect3DTexture9_Release(texture);
14110 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14111 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14112 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14113 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14114 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14116 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14117 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14118 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14119 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14120 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14121 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14123 /* Setup the depth/stencil surface. */
14124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14125 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14127 hr = IDirect3DDevice9_BeginScene(device);
14128 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14131 hr = IDirect3DDevice9_EndScene(device);
14132 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14134 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14135 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14137 hr = IDirect3DDevice9_BeginScene(device);
14138 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14140 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14141 hr = IDirect3DDevice9_EndScene(device);
14142 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14144 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14145 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14146 IDirect3DSurface9_Release(ds);
14147 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14148 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14149 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14150 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14152 /* Read the depth values back. */
14153 hr = IDirect3DDevice9_BeginScene(device);
14154 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14156 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14157 hr = IDirect3DDevice9_EndScene(device);
14158 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14160 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14162 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14163 ok(color_match(color, expected_colors[i].color, 1),
14164 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14165 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14168 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14169 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14171 IDirect3DTexture9_Release(texture);
14172 IDirect3DPixelShader9_Release(ps);
14173 IDirect3DSurface9_Release(original_rt);
14174 IDirect3DSurface9_Release(rt);
14175 refcount = IDirect3DDevice9_Release(device);
14176 ok(!refcount, "Device has %u references left.\n", refcount);
14177 done:
14178 IDirect3D9_Release(d3d);
14179 DestroyWindow(window);
14182 static void shadow_test(void)
14184 static const DWORD ps_code[] =
14186 0xffff0200, /* ps_2_0 */
14187 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14188 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14189 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14190 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14191 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14192 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
14193 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
14194 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
14195 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
14196 0x0000ffff, /* end */
14198 struct
14200 D3DFORMAT format;
14201 const char *name;
14203 formats[] =
14205 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14206 {D3DFMT_D32, "D3DFMT_D32"},
14207 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14208 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14209 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14210 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14211 {D3DFMT_D16, "D3DFMT_D16"},
14212 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14213 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14215 struct
14217 float x, y, z;
14218 float s, t, p, q;
14220 quad[] =
14222 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14223 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14224 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14225 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14227 struct
14229 UINT x, y;
14230 D3DCOLOR color;
14232 expected_colors[] =
14234 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14235 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14236 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14237 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14238 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14239 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14240 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14241 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
14244 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14245 IDirect3DPixelShader9 *ps;
14246 IDirect3DDevice9 *device;
14247 IDirect3D9 *d3d;
14248 ULONG refcount;
14249 D3DCAPS9 caps;
14250 HWND window;
14251 HRESULT hr;
14252 UINT i;
14254 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14255 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14256 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14257 ok(!!d3d, "Failed to create a D3D object.\n");
14258 if (!(device = create_device(d3d, window, window, TRUE)))
14260 skip("Failed to create a D3D device, skipping tests.\n");
14261 goto done;
14264 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14265 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14266 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14268 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14269 IDirect3DDevice9_Release(device);
14270 goto done;
14273 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14274 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14275 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14276 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14278 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14279 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14280 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14281 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14282 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14284 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14285 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14287 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14289 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14291 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14293 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14295 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14296 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14297 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14298 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14299 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14300 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14301 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14302 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14303 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14304 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14306 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14308 D3DFORMAT format = formats[i].format;
14309 IDirect3DTexture9 *texture;
14310 IDirect3DSurface9 *ds;
14311 unsigned int j;
14313 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14314 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14315 continue;
14317 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14318 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14319 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14321 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14322 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14324 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14325 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14327 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14328 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14330 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14331 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14333 /* Setup the depth/stencil surface. */
14334 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14335 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14337 hr = IDirect3DDevice9_BeginScene(device);
14338 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14339 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14340 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14341 hr = IDirect3DDevice9_EndScene(device);
14342 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14344 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14345 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14346 IDirect3DSurface9_Release(ds);
14348 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14349 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14351 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14352 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14354 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14355 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14357 /* Do the actual shadow mapping. */
14358 hr = IDirect3DDevice9_BeginScene(device);
14359 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14361 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14362 hr = IDirect3DDevice9_EndScene(device);
14363 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14365 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14366 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14367 IDirect3DTexture9_Release(texture);
14369 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14371 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
14372 ok(color_match(color, expected_colors[j].color, 0),
14373 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14374 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14375 formats[i].name, color);
14378 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14379 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14382 IDirect3DPixelShader9_Release(ps);
14383 IDirect3DSurface9_Release(original_ds);
14384 IDirect3DSurface9_Release(original_rt);
14385 IDirect3DSurface9_Release(rt);
14386 refcount = IDirect3DDevice9_Release(device);
14387 ok(!refcount, "Device has %u references left.\n", refcount);
14388 done:
14389 IDirect3D9_Release(d3d);
14390 DestroyWindow(window);
14393 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14395 static const struct
14397 struct vec3 position;
14398 DWORD diffuse;
14400 quad1[] =
14402 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14403 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14404 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14405 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14407 quad2[] =
14409 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14410 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14411 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14412 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14414 D3DCOLOR color;
14415 HRESULT hr;
14417 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14418 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14420 hr = IDirect3DDevice9_BeginScene(device);
14421 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14423 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14424 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14427 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14429 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14432 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14434 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14436 hr = IDirect3DDevice9_EndScene(device);
14437 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14439 color = getPixelColor(device, 1, 240);
14440 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14441 color = getPixelColor(device, 638, 240);
14442 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14444 color = getPixelColor(device, 1, 241);
14445 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14446 color = getPixelColor(device, 638, 241);
14447 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14450 static void clip_planes_test(void)
14452 IDirect3DSurface9 *offscreen_surface, *original_rt;
14453 IDirect3DTexture9 *offscreen = NULL;
14454 IDirect3DVertexShader9 *shader;
14455 IDirect3DDevice9 *device;
14456 IDirect3D9 *d3d;
14457 ULONG refcount;
14458 D3DCAPS9 caps;
14459 HWND window;
14460 HRESULT hr;
14462 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14463 static const DWORD shader_code[] =
14465 0xfffe0200, /* vs_2_0 */
14466 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14467 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14468 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14469 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14470 0x0000ffff /* end */
14473 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14474 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14475 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14476 ok(!!d3d, "Failed to create a D3D object.\n");
14477 if (!(device = create_device(d3d, window, window, TRUE)))
14479 skip("Failed to create a D3D device, skipping tests.\n");
14480 goto done;
14483 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14484 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14485 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14487 skip("No vs_2_0 support, skipping tests.\n");
14488 IDirect3DDevice9_Release(device);
14489 goto done;
14492 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14493 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14495 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14496 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14498 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14500 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14502 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14504 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14505 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14506 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14507 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14509 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14511 clip_planes(device, "Onscreen FFP");
14513 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14514 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14515 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14516 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14517 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14518 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14520 clip_planes(device, "Offscreen FFP");
14522 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14523 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14525 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14526 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14527 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14528 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14530 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14531 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14533 clip_planes(device, "Onscreen vertex shader");
14535 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14536 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14538 clip_planes(device, "Offscreen vertex shader");
14540 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14541 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14543 IDirect3DVertexShader9_Release(shader);
14544 IDirect3DSurface9_Release(original_rt);
14545 IDirect3DSurface9_Release(offscreen_surface);
14546 IDirect3DTexture9_Release(offscreen);
14547 refcount = IDirect3DDevice9_Release(device);
14548 ok(!refcount, "Device has %u references left.\n", refcount);
14549 done:
14550 IDirect3D9_Release(d3d);
14551 DestroyWindow(window);
14554 static void fp_special_test(void)
14556 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14557 static const DWORD vs_header[] =
14559 0xfffe0200, /* vs_2_0 */
14560 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14561 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14562 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14563 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14566 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14567 static const DWORD vs_pow[] =
14568 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14569 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14570 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14571 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14572 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14573 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14574 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14575 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14576 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14577 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14578 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14580 static const DWORD vs_footer[] =
14582 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14583 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14584 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14585 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14586 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14587 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14588 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14589 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14590 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14591 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14592 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14593 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14594 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14595 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14596 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14597 0x0000ffff, /* end */
14600 static const struct
14602 const char *name;
14603 const DWORD *ops;
14604 DWORD size;
14605 D3DCOLOR r500;
14606 D3DCOLOR r600;
14607 D3DCOLOR nv40;
14608 D3DCOLOR nv50;
14609 D3DCOLOR warp;
14611 vs_body[] =
14613 /* The basic ideas here are:
14614 * 2.0 * +/-INF == +/-INF
14615 * NAN != NAN
14617 * The vertex shader value is written to the red component, with 0.0
14618 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14619 * result in 0x00. The pixel shader value is written to the green
14620 * component, but here 0.0 also results in 0x00. The actual value is
14621 * written to the blue component.
14623 * There are considerable differences between graphics cards in how
14624 * these are handled, but pow and nrm never generate INF or NAN on
14625 * real hardware. */
14626 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14627 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14628 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14629 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14630 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14631 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14632 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14633 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14634 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14635 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14636 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14639 static const DWORD ps_code[] =
14641 0xffff0200, /* ps_2_0 */
14642 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14643 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14644 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14645 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14646 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14647 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14648 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14649 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14650 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14651 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14652 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14653 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14654 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14655 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14656 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14657 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14658 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14659 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14660 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14661 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14662 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14663 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14664 0x0000ffff, /* end */
14667 struct
14669 float x, y, z;
14670 float s;
14672 quad[] =
14674 { -1.0f, 1.0f, 0.0f, 0.0f},
14675 { 1.0f, 1.0f, 1.0f, 0.0f},
14676 { -1.0f, -1.0f, 0.0f, 0.0f},
14677 { 1.0f, -1.0f, 1.0f, 0.0f},
14680 IDirect3DPixelShader9 *ps;
14681 IDirect3DDevice9 *device;
14682 UINT body_size = 0;
14683 IDirect3D9 *d3d;
14684 DWORD *vs_code;
14685 ULONG refcount;
14686 D3DCAPS9 caps;
14687 HWND window;
14688 HRESULT hr;
14689 UINT i;
14691 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14692 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14693 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14694 ok(!!d3d, "Failed to create a D3D object.\n");
14695 if (!(device = create_device(d3d, window, window, TRUE)))
14697 skip("Failed to create a D3D device, skipping tests.\n");
14698 goto done;
14701 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14702 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14703 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14705 skip("No shader model 2.0 support, skipping floating point specials test.\n");
14706 IDirect3DDevice9_Release(device);
14707 goto done;
14710 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
14711 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14713 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14714 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14715 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14716 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14719 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14721 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
14722 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14724 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14726 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
14729 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
14730 memcpy(vs_code, vs_header, sizeof(vs_header));
14732 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14734 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
14735 IDirect3DVertexShader9 *vs;
14736 D3DCOLOR color;
14738 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
14739 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
14740 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
14742 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
14743 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
14744 hr = IDirect3DDevice9_SetVertexShader(device, vs);
14745 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14747 hr = IDirect3DDevice9_BeginScene(device);
14748 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14749 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14750 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14751 hr = IDirect3DDevice9_EndScene(device);
14752 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14754 color = getPixelColor(device, 320, 240);
14755 ok(color_match(color, vs_body[i].r500, 1)
14756 || color_match(color, vs_body[i].r600, 1)
14757 || color_match(color, vs_body[i].nv40, 1)
14758 || color_match(color, vs_body[i].nv50, 1)
14759 || broken(color_match(color, vs_body[i].warp, 1)),
14760 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
14761 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
14763 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14764 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14766 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14767 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14768 IDirect3DVertexShader9_Release(vs);
14771 HeapFree(GetProcessHeap(), 0, vs_code);
14773 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14774 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14775 IDirect3DPixelShader9_Release(ps);
14776 refcount = IDirect3DDevice9_Release(device);
14777 ok(!refcount, "Device has %u references left.\n", refcount);
14778 done:
14779 IDirect3D9_Release(d3d);
14780 DestroyWindow(window);
14783 static void srgbwrite_format_test(void)
14785 IDirect3D9 *d3d;
14786 IDirect3DSurface9 *rt, *backbuffer;
14787 IDirect3DTexture9 *texture;
14788 IDirect3DDevice9 *device;
14789 ULONG refcount;
14790 HWND window;
14791 HRESULT hr;
14792 int i;
14793 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
14794 static const struct
14796 D3DFORMAT fmt;
14797 const char *name;
14799 formats[] =
14801 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
14802 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
14803 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
14804 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
14805 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
14807 static const struct
14809 float x, y, z;
14810 float u, v;
14812 quad[] =
14814 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14815 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14816 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14817 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14820 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14821 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14823 ok(!!d3d, "Failed to create a D3D object.\n");
14824 if (!(device = create_device(d3d, window, window, TRUE)))
14826 skip("Failed to create a D3D device, skipping tests.\n");
14827 goto done;
14830 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
14831 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14832 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
14833 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
14834 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14835 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
14837 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14839 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
14841 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14842 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
14844 skip("Format %s not supported as render target, skipping test.\n",
14845 formats[i].name);
14846 continue;
14849 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
14850 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
14851 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14853 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14855 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
14856 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14857 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14858 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
14860 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14862 hr = IDirect3DDevice9_BeginScene(device);
14863 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
14866 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
14867 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
14868 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
14869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14870 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
14873 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
14874 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14875 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14876 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
14877 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
14878 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14879 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
14880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14881 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14882 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14883 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
14885 hr = IDirect3DDevice9_EndScene(device);
14886 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14888 IDirect3DSurface9_Release(rt);
14889 IDirect3DTexture9_Release(texture);
14891 color = getPixelColor(device, 360, 240);
14892 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14893 D3DUSAGE_QUERY_SRGBWRITE,
14894 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
14896 /* Big slop for R5G6B5 */
14897 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
14898 formats[i].name, color_srgb, color);
14900 else
14902 /* Big slop for R5G6B5 */
14903 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
14904 formats[i].name, color_rgb, color);
14907 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14908 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14911 IDirect3DSurface9_Release(backbuffer);
14912 refcount = IDirect3DDevice9_Release(device);
14913 ok(!refcount, "Device has %u references left.\n", refcount);
14914 done:
14915 IDirect3D9_Release(d3d);
14916 DestroyWindow(window);
14919 static void ds_size_test(void)
14921 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
14922 IDirect3DDevice9 *device;
14923 DWORD num_passes;
14924 IDirect3D9 *d3d;
14925 ULONG refcount;
14926 HWND window;
14927 HRESULT hr;
14929 static const struct
14931 float x, y, z;
14933 quad[] =
14935 {-1.0f, -1.0f, 0.0f},
14936 {-1.0f, 1.0f, 0.0f},
14937 { 1.0f, -1.0f, 0.0f},
14938 { 1.0f, 1.0f, 0.0f},
14941 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14942 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14943 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14944 ok(!!d3d, "Failed to create a D3D object.\n");
14945 if (!(device = create_device(d3d, window, window, TRUE)))
14947 skip("Failed to create a D3D device, skipping tests.\n");
14948 goto done;
14951 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14952 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14953 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
14954 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
14955 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
14956 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
14958 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14959 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
14961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14962 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
14964 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14966 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14967 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14968 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14969 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14970 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14971 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
14972 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
14973 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14974 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14975 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14976 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14977 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14978 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14980 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
14981 * but does not change the surface's contents. */
14982 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
14983 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
14984 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
14985 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
14986 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
14987 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
14989 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
14991 /* Turning on any depth-related state results in a ValidateDevice failure */
14992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14993 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14994 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14995 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14996 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14998 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15000 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15001 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15002 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15003 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15005 /* Try to draw with the device in an invalid state. */
15006 hr = IDirect3DDevice9_BeginScene(device);
15007 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15008 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15009 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15010 hr = IDirect3DDevice9_EndScene(device);
15011 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15013 /* Don't check the resulting draw unless we find an app that needs it. On
15014 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15015 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15016 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15018 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15020 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15021 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15022 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15023 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15025 IDirect3DSurface9_Release(readback);
15026 IDirect3DSurface9_Release(ds);
15027 IDirect3DSurface9_Release(rt);
15028 IDirect3DSurface9_Release(old_rt);
15029 IDirect3DSurface9_Release(old_ds);
15030 refcount = IDirect3DDevice9_Release(device);
15031 ok(!refcount, "Device has %u references left.\n", refcount);
15032 done:
15033 IDirect3D9_Release(d3d);
15034 DestroyWindow(window);
15037 static void unbound_sampler_test(void)
15039 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15040 IDirect3DSurface9 *rt, *old_rt;
15041 IDirect3DDevice9 *device;
15042 IDirect3D9 *d3d;
15043 ULONG refcount;
15044 D3DCAPS9 caps;
15045 DWORD color;
15046 HWND window;
15047 HRESULT hr;
15049 static const DWORD ps_code[] =
15051 0xffff0200, /* ps_2_0 */
15052 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15053 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15054 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15055 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15056 0x0000ffff, /* end */
15058 static const DWORD ps_code_cube[] =
15060 0xffff0200, /* ps_2_0 */
15061 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15062 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15063 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15064 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15065 0x0000ffff, /* end */
15067 static const DWORD ps_code_volume[] =
15069 0xffff0200, /* ps_2_0 */
15070 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15071 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15072 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15073 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15074 0x0000ffff, /* end */
15077 static const struct
15079 float x, y, z;
15080 float u, v;
15082 quad[] =
15084 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15085 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15086 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15087 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15090 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15091 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15092 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15093 ok(!!d3d, "Failed to create a D3D object.\n");
15094 if (!(device = create_device(d3d, window, window, TRUE)))
15096 skip("Failed to create a D3D device, skipping tests.\n");
15097 goto done;
15100 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15101 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15102 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15104 skip("No ps_2_0 support, skipping tests.\n");
15105 IDirect3DDevice9_Release(device);
15106 goto done;
15108 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15110 skip("No cube / volume texture support, skipping tests.\n");
15111 IDirect3DDevice9_Release(device);
15112 goto done;
15115 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15116 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15118 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15119 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15120 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15121 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15122 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15123 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15125 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15126 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15128 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15129 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15131 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15134 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15135 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15137 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15138 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15140 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15141 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15143 hr = IDirect3DDevice9_BeginScene(device);
15144 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15146 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15147 hr = IDirect3DDevice9_EndScene(device);
15148 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15150 color = getPixelColorFromSurface(rt, 32, 32);
15151 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15153 /* Now try with a cube texture */
15154 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15155 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15157 hr = IDirect3DDevice9_BeginScene(device);
15158 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15160 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15161 hr = IDirect3DDevice9_EndScene(device);
15162 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15164 color = getPixelColorFromSurface(rt, 32, 32);
15165 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15167 /* And then with a volume texture */
15168 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15169 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15171 hr = IDirect3DDevice9_BeginScene(device);
15172 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15174 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15175 hr = IDirect3DDevice9_EndScene(device);
15176 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15178 color = getPixelColorFromSurface(rt, 32, 32);
15179 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15181 IDirect3DSurface9_Release(rt);
15182 IDirect3DSurface9_Release(old_rt);
15183 IDirect3DPixelShader9_Release(ps);
15184 IDirect3DPixelShader9_Release(ps_cube);
15185 IDirect3DPixelShader9_Release(ps_volume);
15186 refcount = IDirect3DDevice9_Release(device);
15187 ok(!refcount, "Device has %u references left.\n", refcount);
15188 done:
15189 IDirect3D9_Release(d3d);
15190 DestroyWindow(window);
15193 static void update_surface_test(void)
15195 static const BYTE blocks[][8] =
15197 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15198 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15199 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15200 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15201 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15202 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15203 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15205 static const struct
15207 UINT x, y;
15208 D3DCOLOR color;
15210 expected_colors[] =
15212 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15213 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15214 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15215 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15216 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15217 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15218 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15220 static const struct
15222 float x, y, z, w;
15223 float u, v;
15225 tri[] =
15227 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15228 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15229 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15231 static const RECT rect_2x2 = {0, 0, 2, 2};
15232 static const struct
15234 UINT src_level;
15235 UINT dst_level;
15236 const RECT *r;
15237 HRESULT hr;
15239 block_size_tests[] =
15241 {1, 0, NULL, D3D_OK},
15242 {0, 1, NULL, D3DERR_INVALIDCALL},
15243 {5, 4, NULL, D3DERR_INVALIDCALL},
15244 {4, 5, NULL, D3DERR_INVALIDCALL},
15245 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15246 {5, 5, &rect_2x2, D3D_OK},
15249 IDirect3DSurface9 *src_surface, *dst_surface;
15250 IDirect3DTexture9 *src_tex, *dst_tex;
15251 IDirect3DDevice9 *device;
15252 IDirect3D9 *d3d;
15253 ULONG refcount;
15254 UINT count, i;
15255 HWND window;
15256 HRESULT hr;
15258 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15259 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15260 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15261 ok(!!d3d, "Failed to create a D3D object.\n");
15262 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15263 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15265 skip("DXT1 not supported, skipping tests.\n");
15266 goto done;
15268 if (!(device = create_device(d3d, window, window, TRUE)))
15270 skip("Failed to create a D3D device, skipping tests.\n");
15271 goto done;
15274 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15275 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15276 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15277 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15279 count = IDirect3DTexture9_GetLevelCount(src_tex);
15280 ok(count == 7, "Got level count %u, expected 7.\n", count);
15282 for (i = 0; i < count; ++i)
15284 UINT row_count, block_count, x, y;
15285 D3DSURFACE_DESC desc;
15286 BYTE *row, *block;
15287 D3DLOCKED_RECT r;
15289 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15290 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15292 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15293 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15295 row_count = ((desc.Height + 3) & ~3) / 4;
15296 block_count = ((desc.Width + 3) & ~3) / 4;
15297 row = r.pBits;
15299 for (y = 0; y < row_count; ++y)
15301 block = row;
15302 for (x = 0; x < block_count; ++x)
15304 memcpy(block, blocks[i], sizeof(blocks[i]));
15305 block += sizeof(blocks[i]);
15307 row += r.Pitch;
15310 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15311 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15314 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15316 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15317 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15318 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15319 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15321 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15322 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15323 hr, i, block_size_tests[i].hr);
15325 IDirect3DSurface9_Release(dst_surface);
15326 IDirect3DSurface9_Release(src_surface);
15329 for (i = 0; i < count; ++i)
15331 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15332 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15333 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15334 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15336 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15337 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15339 IDirect3DSurface9_Release(dst_surface);
15340 IDirect3DSurface9_Release(src_surface);
15343 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15344 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15345 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15346 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15347 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15348 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15349 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15350 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15351 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15352 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15353 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15354 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15357 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15359 hr = IDirect3DDevice9_BeginScene(device);
15360 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15362 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15363 hr = IDirect3DDevice9_EndScene(device);
15364 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15366 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15368 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15369 ok(color_match(color, expected_colors[i].color, 0),
15370 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15371 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15375 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15377 IDirect3DTexture9_Release(dst_tex);
15378 IDirect3DTexture9_Release(src_tex);
15379 refcount = IDirect3DDevice9_Release(device);
15380 ok(!refcount, "Device has %u references left.\n", refcount);
15381 done:
15382 IDirect3D9_Release(d3d);
15383 DestroyWindow(window);
15386 static void multisample_get_rtdata_test(void)
15388 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15389 IDirect3DDevice9 *device;
15390 IDirect3D9 *d3d;
15391 ULONG refcount;
15392 HWND window;
15393 HRESULT hr;
15395 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15396 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15397 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15398 ok(!!d3d, "Failed to create a D3D object.\n");
15399 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15400 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15402 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15403 goto done;
15405 if (!(device = create_device(d3d, window, window, TRUE)))
15407 skip("Failed to create a D3D device, skipping tests.\n");
15408 goto done;
15411 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15412 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15413 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15414 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15415 D3DPOOL_SYSTEMMEM, &readback, NULL);
15416 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15418 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15419 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15420 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15421 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15423 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15424 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15425 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15426 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15428 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15429 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15430 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15431 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15433 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15434 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15435 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15436 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15438 IDirect3DSurface9_Release(original_ds);
15439 IDirect3DSurface9_Release(original_rt);
15440 IDirect3DSurface9_Release(readback);
15441 IDirect3DSurface9_Release(rt);
15442 refcount = IDirect3DDevice9_Release(device);
15443 ok(!refcount, "Device has %u references left.\n", refcount);
15444 done:
15445 IDirect3D9_Release(d3d);
15446 DestroyWindow(window);
15449 static void multisampled_depth_buffer_test(void)
15451 IDirect3DDevice9 *device = 0;
15452 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15453 IDirect3D9 *d3d;
15454 D3DCAPS9 caps;
15455 HRESULT hr;
15456 D3DPRESENT_PARAMETERS present_parameters;
15457 unsigned int i;
15458 static const struct
15460 float x, y, z;
15461 D3DCOLOR color;
15463 quad_1[] =
15465 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15466 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15467 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15468 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15470 quad_2[] =
15472 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15473 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15474 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15475 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15477 static const struct
15479 UINT x, y;
15480 D3DCOLOR color;
15482 expected_colors[] =
15484 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15485 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15486 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15487 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15488 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15489 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15490 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15491 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15494 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15495 ok(!!d3d, "Failed to create a D3D object.\n");
15497 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15498 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15500 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15501 IDirect3D9_Release(d3d);
15502 return;
15504 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15505 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15507 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15508 IDirect3D9_Release(d3d);
15509 return;
15512 ZeroMemory(&present_parameters, sizeof(present_parameters));
15513 present_parameters.Windowed = TRUE;
15514 present_parameters.hDeviceWindow = create_window();
15515 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15516 present_parameters.BackBufferWidth = 640;
15517 present_parameters.BackBufferHeight = 480;
15518 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15519 present_parameters.EnableAutoDepthStencil = TRUE;
15520 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15521 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15523 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15524 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15525 &present_parameters, &device);
15526 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15528 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15529 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15530 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15532 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15533 goto cleanup;
15536 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15537 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15538 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15539 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15540 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15541 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15543 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15544 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15545 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15546 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15553 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15555 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15556 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15557 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15560 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15562 /* Render onscreen and then offscreen */
15563 hr = IDirect3DDevice9_BeginScene(device);
15564 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15566 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15567 hr = IDirect3DDevice9_EndScene(device);
15568 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15570 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15571 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15572 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15573 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15575 hr = IDirect3DDevice9_BeginScene(device);
15576 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15578 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15579 hr = IDirect3DDevice9_EndScene(device);
15580 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15582 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15583 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15585 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15587 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15588 ok(color_match(color, expected_colors[i].color, 1),
15589 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15590 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15593 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15594 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15596 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15598 /* Render offscreen and then onscreen */
15599 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15600 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15601 IDirect3DSurface9_Release(ds);
15602 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15603 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15604 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15605 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15606 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15608 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15609 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15611 hr = IDirect3DDevice9_BeginScene(device);
15612 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15614 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15615 hr = IDirect3DDevice9_EndScene(device);
15616 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15618 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15619 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15620 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15621 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15623 hr = IDirect3DDevice9_BeginScene(device);
15624 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15626 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15627 hr = IDirect3DDevice9_EndScene(device);
15628 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15630 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15631 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15633 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15635 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15636 ok(color_match(color, expected_colors[i].color, 1),
15637 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15638 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15642 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15644 IDirect3DSurface9_Release(ds);
15645 IDirect3DSurface9_Release(readback);
15646 IDirect3DSurface9_Release(rt);
15647 IDirect3DSurface9_Release(original_rt);
15648 cleanup_device(device);
15650 ZeroMemory(&present_parameters, sizeof(present_parameters));
15651 present_parameters.Windowed = TRUE;
15652 present_parameters.hDeviceWindow = create_window();
15653 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15654 present_parameters.BackBufferWidth = 640;
15655 present_parameters.BackBufferHeight = 480;
15656 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15657 present_parameters.EnableAutoDepthStencil = TRUE;
15658 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15659 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15661 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15662 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15663 &present_parameters, &device);
15664 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15666 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15667 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15669 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15670 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15671 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15672 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15673 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15674 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15675 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15676 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15677 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15679 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15680 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15681 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15682 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15683 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15684 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15685 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15686 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15689 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15691 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15693 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15695 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15696 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15697 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15699 /* Render to a multisampled offscreen frame buffer and then blit to
15700 * the onscreen (not multisampled) frame buffer. */
15701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15702 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15704 hr = IDirect3DDevice9_BeginScene(device);
15705 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15707 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15708 hr = IDirect3DDevice9_EndScene(device);
15709 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15711 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15712 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15713 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
15714 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15716 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15717 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15718 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15719 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15721 hr = IDirect3DDevice9_BeginScene(device);
15722 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15723 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15724 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15725 hr = IDirect3DDevice9_EndScene(device);
15726 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15728 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15729 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15731 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15733 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15734 ok(color_match(color, expected_colors[i].color, 1),
15735 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15736 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15739 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15740 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15742 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15743 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15744 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15745 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15747 IDirect3DSurface9_Release(original_ds);
15748 IDirect3DSurface9_Release(original_rt);
15749 IDirect3DSurface9_Release(ds);
15750 IDirect3DSurface9_Release(readback);
15751 IDirect3DSurface9_Release(rt);
15752 cleanup:
15753 cleanup_device(device);
15754 IDirect3D9_Release(d3d);
15757 static void resz_test(void)
15759 IDirect3DDevice9 *device = 0;
15760 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
15761 D3DCAPS9 caps;
15762 HRESULT hr;
15763 D3DPRESENT_PARAMETERS present_parameters;
15764 unsigned int i;
15765 static const DWORD ps_code[] =
15767 0xffff0200, /* ps_2_0 */
15768 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15769 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15770 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
15771 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
15772 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15773 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
15774 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
15775 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
15776 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
15777 0x0000ffff, /* end */
15779 struct
15781 float x, y, z;
15782 float s, t, p, q;
15784 quad[] =
15786 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15787 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15788 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15789 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15791 struct
15793 UINT x, y;
15794 D3DCOLOR color;
15796 expected_colors[] =
15798 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15799 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15800 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15801 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15802 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15803 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15804 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15805 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15807 IDirect3DTexture9 *texture;
15808 IDirect3DPixelShader9 *ps;
15809 IDirect3D9 *d3d;
15810 DWORD value;
15812 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15813 ok(!!d3d, "Failed to create a D3D object.\n");
15815 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15816 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15818 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
15819 IDirect3D9_Release(d3d);
15820 return;
15822 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15823 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15825 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
15826 IDirect3D9_Release(d3d);
15827 return;
15830 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15831 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
15833 skip("No INTZ support, skipping RESZ test.\n");
15834 IDirect3D9_Release(d3d);
15835 return;
15838 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15839 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
15841 skip("No RESZ support, skipping RESZ test.\n");
15842 IDirect3D9_Release(d3d);
15843 return;
15846 ZeroMemory(&present_parameters, sizeof(present_parameters));
15847 present_parameters.Windowed = TRUE;
15848 present_parameters.hDeviceWindow = create_window();
15849 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15850 present_parameters.BackBufferWidth = 640;
15851 present_parameters.BackBufferHeight = 480;
15852 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15853 present_parameters.EnableAutoDepthStencil = FALSE;
15854 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15855 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15857 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15858 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15859 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15861 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15862 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15863 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15865 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
15866 cleanup_device(device);
15867 IDirect3D9_Release(d3d);
15868 return;
15870 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15872 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
15873 cleanup_device(device);
15874 IDirect3D9_Release(d3d);
15875 return;
15878 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15879 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15881 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15882 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15883 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15884 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15885 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15886 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15887 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15888 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15889 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15891 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15892 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15893 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15894 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15895 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15896 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15897 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15898 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15899 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15900 IDirect3DSurface9_Release(intz_ds);
15901 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15902 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15904 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15905 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15907 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15909 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15911 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15913 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15915 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15916 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15917 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15918 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15919 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15920 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15921 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15922 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15923 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15924 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15926 /* Render offscreen (multisampled), blit the depth buffer
15927 * into the INTZ texture and then check its contents */
15928 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15929 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15930 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15931 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15933 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15935 hr = IDirect3DDevice9_BeginScene(device);
15936 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15938 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15940 /* The destination depth texture has to be bound to sampler 0 */
15941 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15942 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15944 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
15945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15946 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15948 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15950 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15952 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15953 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15954 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15956 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15958 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15960 /* The actual multisampled depth buffer resolve happens here */
15961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15962 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15963 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15964 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15966 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15967 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15968 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15969 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15970 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15971 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15973 /* Read the depth values back */
15974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15975 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15976 hr = IDirect3DDevice9_EndScene(device);
15977 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15979 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15981 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15982 ok(color_match(color, expected_colors[i].color, 1),
15983 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15984 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15987 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15988 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15990 IDirect3DSurface9_Release(ds);
15991 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15992 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15993 IDirect3DTexture9_Release(texture);
15994 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15995 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15996 IDirect3DPixelShader9_Release(ps);
15997 IDirect3DSurface9_Release(readback);
15998 IDirect3DSurface9_Release(original_rt);
15999 IDirect3DSurface9_Release(rt);
16000 cleanup_device(device);
16002 ZeroMemory(&present_parameters, sizeof(present_parameters));
16003 present_parameters.Windowed = TRUE;
16004 present_parameters.hDeviceWindow = create_window();
16005 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16006 present_parameters.BackBufferWidth = 640;
16007 present_parameters.BackBufferHeight = 480;
16008 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16009 present_parameters.EnableAutoDepthStencil = TRUE;
16010 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16011 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16013 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16014 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16015 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16017 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16018 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16019 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16020 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16021 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16022 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16023 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16024 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16025 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16026 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16027 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16028 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16029 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16030 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16031 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16032 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16034 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16035 IDirect3DSurface9_Release(intz_ds);
16036 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16037 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16039 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16040 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16042 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16044 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16046 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16048 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16050 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16051 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16052 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16053 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16054 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16055 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16056 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16057 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16058 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16059 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16061 /* Render onscreen, blit the depth buffer into the INTZ texture
16062 * and then check its contents */
16063 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16064 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16065 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16066 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16068 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16070 hr = IDirect3DDevice9_BeginScene(device);
16071 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16073 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16074 hr = IDirect3DDevice9_EndScene(device);
16075 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16077 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16078 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16081 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16083 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16085 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16087 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16089 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16091 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16093 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16095 /* The actual multisampled depth buffer resolve happens here */
16096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16097 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16098 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16099 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16101 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16102 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16103 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16104 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16105 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16106 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16108 /* Read the depth values back */
16109 hr = IDirect3DDevice9_BeginScene(device);
16110 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16112 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16113 hr = IDirect3DDevice9_EndScene(device);
16114 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16116 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16118 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16119 ok(color_match(color, expected_colors[i].color, 1),
16120 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16121 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16124 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16125 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16128 /* Test edge cases - try with no texture at all */
16129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16130 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16131 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16132 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16133 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16134 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16135 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16136 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16138 hr = IDirect3DDevice9_BeginScene(device);
16139 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16141 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16142 hr = IDirect3DDevice9_EndScene(device);
16143 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16146 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16148 /* With a non-multisampled depth buffer */
16149 IDirect3DSurface9_Release(ds);
16150 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16151 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16153 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16154 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16155 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16156 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16157 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16158 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16160 hr = IDirect3DDevice9_BeginScene(device);
16161 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16163 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16165 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16166 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16169 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16171 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16173 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16175 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16177 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16179 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16180 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16181 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16182 hr = IDirect3DDevice9_EndScene(device);
16183 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16186 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16188 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16189 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16191 /* Read the depth values back. */
16192 hr = IDirect3DDevice9_BeginScene(device);
16193 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16194 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16195 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16196 hr = IDirect3DDevice9_EndScene(device);
16197 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16199 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16201 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16202 ok(color_match(color, expected_colors[i].color, 1),
16203 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16204 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16207 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16208 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16210 /* Without a current depth-stencil buffer set */
16211 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16212 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16213 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16214 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16216 hr = IDirect3DDevice9_BeginScene(device);
16217 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16219 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16220 hr = IDirect3DDevice9_EndScene(device);
16221 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16224 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16226 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16227 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16228 IDirect3DSurface9_Release(ds);
16229 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16230 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16231 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16232 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16233 IDirect3DTexture9_Release(texture);
16234 IDirect3DPixelShader9_Release(ps);
16235 IDirect3DSurface9_Release(readback);
16236 IDirect3DSurface9_Release(original_rt);
16237 cleanup_device(device);
16238 IDirect3D9_Release(d3d);
16241 static void zenable_test(void)
16243 static const struct
16245 struct vec4 position;
16246 D3DCOLOR diffuse;
16248 tquad[] =
16250 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16251 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16252 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16253 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16255 IDirect3DDevice9 *device;
16256 IDirect3D9 *d3d;
16257 D3DCOLOR color;
16258 ULONG refcount;
16259 D3DCAPS9 caps;
16260 HWND window;
16261 HRESULT hr;
16262 UINT x, y;
16263 UINT i, j;
16264 UINT test;
16265 IDirect3DSurface9 *ds;
16267 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16268 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16269 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16270 ok(!!d3d, "Failed to create a D3D object.\n");
16271 if (!(device = create_device(d3d, window, window, TRUE)))
16273 skip("Failed to create a D3D device, skipping tests.\n");
16274 goto done;
16277 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16278 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16280 for (test = 0; test < 2; ++test)
16282 /* The Windows 8 testbot (WARP) appears to clip with
16283 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16284 static const D3DCOLOR expected_broken[] =
16286 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16287 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16288 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16289 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16292 if (!test)
16294 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16295 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16297 else
16299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16300 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16301 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16302 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16304 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16306 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16307 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16309 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16310 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16311 hr = IDirect3DDevice9_BeginScene(device);
16312 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16314 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16315 hr = IDirect3DDevice9_EndScene(device);
16316 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16318 for (i = 0; i < 4; ++i)
16320 for (j = 0; j < 4; ++j)
16322 x = 80 * ((2 * j) + 1);
16323 y = 60 * ((2 * i) + 1);
16324 color = getPixelColor(device, x, y);
16325 ok(color_match(color, 0x0000ff00, 1)
16326 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16327 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16328 x, y, color, test);
16332 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16333 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16336 IDirect3DSurface9_Release(ds);
16338 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16339 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16341 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16342 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16344 static const DWORD vs_code[] =
16346 0xfffe0101, /* vs_1_1 */
16347 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16348 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16349 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16350 0x0000ffff
16352 static const DWORD ps_code[] =
16354 0xffff0101, /* ps_1_1 */
16355 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16356 0x0000ffff /* end */
16358 static const struct vec3 quad[] =
16360 {-1.0f, -1.0f, -0.5f},
16361 {-1.0f, 1.0f, -0.5f},
16362 { 1.0f, -1.0f, 1.5f},
16363 { 1.0f, 1.0f, 1.5f},
16365 static const D3DCOLOR expected[] =
16367 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16368 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16369 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16370 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16372 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16373 * vertices either. */
16374 static const D3DCOLOR expected_broken[] =
16376 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16377 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16378 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16379 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16382 IDirect3DVertexShader9 *vs;
16383 IDirect3DPixelShader9 *ps;
16385 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16386 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16387 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16388 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16389 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16390 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16391 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16392 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16393 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16394 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16396 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16397 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16398 hr = IDirect3DDevice9_BeginScene(device);
16399 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16401 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16402 hr = IDirect3DDevice9_EndScene(device);
16403 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16405 for (i = 0; i < 4; ++i)
16407 for (j = 0; j < 4; ++j)
16409 x = 80 * ((2 * j) + 1);
16410 y = 60 * ((2 * i) + 1);
16411 color = getPixelColor(device, x, y);
16412 ok(color_match(color, expected[i * 4 + j], 1)
16413 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16414 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16418 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16419 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16421 IDirect3DPixelShader9_Release(ps);
16422 IDirect3DVertexShader9_Release(vs);
16425 refcount = IDirect3DDevice9_Release(device);
16426 ok(!refcount, "Device has %u references left.\n", refcount);
16427 done:
16428 IDirect3D9_Release(d3d);
16429 DestroyWindow(window);
16432 static void fog_special_test(void)
16434 static const struct
16436 struct vec3 position;
16437 D3DCOLOR diffuse;
16439 quad[] =
16441 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16442 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16443 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16444 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16446 static const struct
16448 DWORD vertexmode, tablemode;
16449 BOOL vs, ps;
16450 D3DCOLOR color_left, color_right;
16452 tests[] =
16454 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16455 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16456 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16457 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16459 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16460 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16461 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16462 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16464 static const DWORD pixel_shader_code[] =
16466 0xffff0101, /* ps_1_1 */
16467 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16468 0x0000ffff
16470 static const DWORD vertex_shader_code[] =
16472 0xfffe0101, /* vs_1_1 */
16473 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16474 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16475 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16476 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16477 0x0000ffff
16479 static const D3DMATRIX identity =
16481 1.0f, 0.0f, 0.0f, 0.0f,
16482 0.0f, 1.0f, 0.0f, 0.0f,
16483 0.0f, 0.0f, 1.0f, 0.0f,
16484 0.0f, 0.0f, 0.0f, 1.0f,
16485 }}};
16486 union
16488 float f;
16489 DWORD d;
16490 } conv;
16491 DWORD color;
16492 HRESULT hr;
16493 unsigned int i;
16494 IDirect3DPixelShader9 *ps;
16495 IDirect3DVertexShader9 *vs;
16496 IDirect3DDevice9 *device;
16497 IDirect3D9 *d3d;
16498 ULONG refcount;
16499 D3DCAPS9 caps;
16500 HWND window;
16502 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16503 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16504 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16505 ok(!!d3d, "Failed to create a D3D object.\n");
16506 if (!(device = create_device(d3d, window, window, TRUE)))
16508 skip("Failed to create a D3D device, skipping tests.\n");
16509 goto done;
16512 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16513 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16514 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16516 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16517 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16519 else
16521 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16522 vs = NULL;
16524 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16526 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16527 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16529 else
16531 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16532 ps = NULL;
16535 /* The table fog tests seem to depend on the projection matrix explicitly
16536 * being set to an identity matrix, even though that's the default.
16537 * (AMD Radeon HD 6310, Windows 7) */
16538 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16539 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16541 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16542 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16544 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16546 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16548 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16550 conv.f = 0.5f;
16551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16552 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16554 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16556 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16558 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16559 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16561 if (!tests[i].vs)
16563 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16564 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16566 else if (vs)
16568 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16569 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16571 else
16573 continue;
16576 if (!tests[i].ps)
16578 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16579 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16581 else if (ps)
16583 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16584 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16586 else
16588 continue;
16591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16592 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16594 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16596 hr = IDirect3DDevice9_BeginScene(device);
16597 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16598 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16599 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16600 hr = IDirect3DDevice9_EndScene(device);
16601 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16603 color = getPixelColor(device, 310, 240);
16604 ok(color_match(color, tests[i].color_left, 1),
16605 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16606 color = getPixelColor(device, 330, 240);
16607 ok(color_match(color, tests[i].color_right, 1),
16608 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16611 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16614 if (vs)
16615 IDirect3DVertexShader9_Release(vs);
16616 if (ps)
16617 IDirect3DPixelShader9_Release(ps);
16618 refcount = IDirect3DDevice9_Release(device);
16619 ok(!refcount, "Device has %u references left.\n", refcount);
16620 done:
16621 IDirect3D9_Release(d3d);
16622 DestroyWindow(window);
16625 static void volume_srgb_test(void)
16627 HRESULT hr;
16628 unsigned int i, j;
16629 IDirect3DVolumeTexture9 *tex1, *tex2;
16630 D3DPOOL pool;
16631 D3DLOCKED_BOX locked_box;
16632 IDirect3DDevice9 *device;
16633 IDirect3D9 *d3d;
16634 D3DCOLOR color;
16635 ULONG refcount;
16636 HWND window;
16638 static const struct
16640 BOOL srgb;
16641 DWORD color;
16643 tests[] =
16645 /* Try toggling on and off */
16646 { FALSE, 0x007f7f7f },
16647 { TRUE, 0x00363636 },
16648 { FALSE, 0x007f7f7f },
16650 static const struct
16652 struct vec3 pos;
16653 struct vec3 texcrd;
16655 quad[] =
16657 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16658 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16659 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16660 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16663 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16664 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16665 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16666 ok(!!d3d, "Failed to create a D3D object.\n");
16667 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16668 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16670 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16671 goto done;
16673 if (!(device = create_device(d3d, window, window, TRUE)))
16675 skip("Failed to create a D3D device, skipping tests.\n");
16676 goto done;
16679 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16680 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16681 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16682 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16683 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16684 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16685 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16686 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16688 for (i = 0; i < 2; i++)
16690 if (!i)
16691 pool = D3DPOOL_SYSTEMMEM;
16692 else
16693 pool = D3DPOOL_MANAGED;
16695 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
16696 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16697 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
16698 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16699 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
16700 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
16701 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16703 if (!i)
16705 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
16706 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
16707 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16708 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
16709 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16710 IDirect3DVolumeTexture9_Release(tex1);
16712 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
16713 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16714 IDirect3DVolumeTexture9_Release(tex2);
16716 else
16718 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
16719 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16720 IDirect3DVolumeTexture9_Release(tex1);
16723 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
16725 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
16726 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
16728 hr = IDirect3DDevice9_BeginScene(device);
16729 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16731 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16732 hr = IDirect3DDevice9_EndScene(device);
16733 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16735 color = getPixelColor(device, 320, 240);
16736 ok(color_match(color, tests[j].color, 2),
16737 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
16739 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16740 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16744 refcount = IDirect3DDevice9_Release(device);
16745 ok(!refcount, "Device has %u references left.\n", refcount);
16746 done:
16747 IDirect3D9_Release(d3d);
16748 DestroyWindow(window);
16751 static void volume_dxt5_test(void)
16753 IDirect3DVolumeTexture9 *texture;
16754 IDirect3DDevice9 *device;
16755 D3DLOCKED_BOX box;
16756 IDirect3D9 *d3d;
16757 unsigned int i;
16758 ULONG refcount;
16759 DWORD color;
16760 HWND window;
16761 HRESULT hr;
16763 static const char texture_data[] =
16765 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
16766 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
16767 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
16768 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
16769 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
16771 static const struct
16773 struct vec3 position;
16774 struct vec3 texcrd;
16776 quads[] =
16778 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16779 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16780 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16781 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16783 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16784 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16785 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16786 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16788 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
16790 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16791 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16792 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16793 ok(!!d3d, "Failed to create a D3D object.\n");
16794 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16795 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
16797 skip("DXT5 volume textures are not supported, skipping test.\n");
16798 goto done;
16800 if (!(device = create_device(d3d, window, window, TRUE)))
16802 skip("Failed to create a D3D device, skipping tests.\n");
16803 goto done;
16806 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
16807 D3DPOOL_MANAGED, &texture, NULL);
16808 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16810 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16811 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16812 memcpy(box.pBits, texture_data, sizeof(texture_data));
16813 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16814 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16816 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16817 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16818 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16819 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16820 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16821 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16822 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16823 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16824 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16825 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16826 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16827 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
16829 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16830 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16831 hr = IDirect3DDevice9_BeginScene(device);
16832 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16834 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16835 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16837 hr = IDirect3DDevice9_EndScene(device);
16838 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16840 for (i = 0; i < 4; i++)
16842 color = getPixelColor(device, 80 + 160 * i, 240);
16843 ok (color_match(color, expected_colors[i], 1),
16844 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
16847 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16848 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16849 IDirect3DVolumeTexture9_Release(texture);
16850 refcount = IDirect3DDevice9_Release(device);
16851 ok(!refcount, "Device has %u references left.\n", refcount);
16852 done:
16853 IDirect3D9_Release(d3d);
16854 DestroyWindow(window);
16857 static void volume_v16u16_test(void)
16859 IDirect3DVolumeTexture9 *texture;
16860 IDirect3DPixelShader9 *shader;
16861 IDirect3DDevice9 *device;
16862 D3DLOCKED_BOX box;
16863 IDirect3D9 *d3d;
16864 unsigned int i;
16865 ULONG refcount;
16866 D3DCAPS9 caps;
16867 SHORT *texel;
16868 DWORD color;
16869 HWND window;
16870 HRESULT hr;
16872 static const struct
16874 struct vec3 position;
16875 struct vec3 texcrd;
16877 quads[] =
16879 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16880 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16881 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16882 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16884 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16885 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16886 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16887 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16889 static const DWORD shader_code[] =
16891 0xffff0101, /* ps_1_1 */
16892 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
16893 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
16894 0x00000042, 0xb00f0000, /* tex t0 */
16895 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
16896 0x0000ffff /* end */
16899 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16900 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16901 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16902 ok(!!d3d, "Failed to create a D3D object.\n");
16903 if (!(device = create_device(d3d, window, window, TRUE)))
16905 skip("Failed to create a D3D device, skipping tests.\n");
16906 goto done;
16909 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16910 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16911 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
16913 skip("No ps_1_1 support, skipping tests.\n");
16914 IDirect3DDevice9_Release(device);
16915 goto done;
16917 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16918 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
16920 skip("Volume V16U16 textures are not supported, skipping test.\n");
16921 IDirect3DDevice9_Release(device);
16922 goto done;
16925 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16926 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16927 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
16928 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16929 hr = IDirect3DDevice9_SetPixelShader(device, shader);
16930 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16931 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16932 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
16934 for (i = 0; i < 2; i++)
16936 D3DPOOL pool;
16938 if (i)
16939 pool = D3DPOOL_SYSTEMMEM;
16940 else
16941 pool = D3DPOOL_MANAGED;
16943 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16944 pool, &texture, NULL);
16945 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16947 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16948 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16950 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
16951 texel[0] = 32767;
16952 texel[1] = 32767;
16953 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
16954 texel[0] = -32768;
16955 texel[1] = 0;
16956 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
16957 texel[0] = -16384;
16958 texel[1] = 16384;
16959 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
16960 texel[0] = 0;
16961 texel[1] = 0;
16963 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16964 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16966 if (i)
16968 IDirect3DVolumeTexture9 *texture2;
16970 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16971 D3DPOOL_DEFAULT, &texture2, NULL);
16972 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16974 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
16975 (IDirect3DBaseTexture9 *)texture2);
16976 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16978 IDirect3DVolumeTexture9_Release(texture);
16979 texture = texture2;
16982 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
16983 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16985 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16986 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16987 hr = IDirect3DDevice9_BeginScene(device);
16988 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16990 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16992 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16993 hr = IDirect3DDevice9_EndScene(device);
16994 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16996 color = getPixelColor(device, 120, 160);
16997 ok (color_match(color, 0x000080ff, 2),
16998 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
16999 color = getPixelColor(device, 120, 400);
17000 ok (color_match(color, 0x00ffffff, 2),
17001 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17002 color = getPixelColor(device, 360, 160);
17003 ok (color_match(color, 0x007f7fff, 2),
17004 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17005 color = getPixelColor(device, 360, 400);
17006 ok (color_match(color, 0x0040c0ff, 2),
17007 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17009 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17010 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17012 IDirect3DVolumeTexture9_Release(texture);
17015 IDirect3DPixelShader9_Release(shader);
17016 refcount = IDirect3DDevice9_Release(device);
17017 ok(!refcount, "Device has %u references left.\n", refcount);
17018 done:
17019 IDirect3D9_Release(d3d);
17020 DestroyWindow(window);
17023 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17025 HRESULT hr;
17026 static const struct
17028 struct vec3 position;
17029 struct vec2 texcoord;
17031 quad[] =
17033 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17034 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17035 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17036 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17039 hr = IDirect3DDevice9_BeginScene(device);
17040 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17042 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17043 hr = IDirect3DDevice9_EndScene(device);
17044 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17047 static void add_dirty_rect_test(void)
17049 HRESULT hr;
17050 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
17051 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
17052 IDirect3DDevice9 *device;
17053 IDirect3D9 *d3d;
17054 unsigned int i;
17055 ULONG refcount;
17056 DWORD *texel;
17057 HWND window;
17058 D3DLOCKED_RECT locked_rect;
17059 static const RECT part_rect = {96, 96, 160, 160};
17060 DWORD color;
17062 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17063 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17064 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17065 ok(!!d3d, "Failed to create a D3D object.\n");
17066 if (!(device = create_device(d3d, window, window, TRUE)))
17068 skip("Failed to create a D3D device, skipping tests.\n");
17069 IDirect3D9_Release(d3d);
17070 DestroyWindow(window);
17071 return;
17074 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17075 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17076 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17077 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17078 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17079 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17080 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17081 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17082 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17083 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17084 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17085 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17086 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17087 D3DPOOL_MANAGED, &tex_managed, NULL);
17088 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17090 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17091 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17092 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17093 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17094 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17095 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17096 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17097 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17099 fill_surface(surface_src_red, 0x00ff0000, 0);
17100 fill_surface(surface_src_green, 0x0000ff00, 0);
17102 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17103 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17104 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17105 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17106 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17107 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17109 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17110 (IDirect3DBaseTexture9 *)tex_dst1);
17111 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17113 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17114 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17115 (IDirect3DBaseTexture9 *)tex_dst2);
17116 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17117 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17118 (IDirect3DBaseTexture9 *)tex_dst2);
17119 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17121 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17122 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17123 add_dirty_rect_test_draw(device);
17124 color = getPixelColor(device, 320, 240);
17125 ok(color_match(color, 0x0000ff00, 1),
17126 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17127 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17128 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17130 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17131 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17132 add_dirty_rect_test_draw(device);
17133 color = getPixelColor(device, 320, 240);
17134 todo_wine ok(color_match(color, 0x00ff0000, 1),
17135 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17136 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17137 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17139 /* AddDirtyRect on the destination is ignored. */
17140 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17141 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17142 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17143 (IDirect3DBaseTexture9 *)tex_dst2);
17144 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17145 add_dirty_rect_test_draw(device);
17146 color = getPixelColor(device, 320, 240);
17147 todo_wine ok(color_match(color, 0x00ff0000, 1),
17148 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17149 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17150 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17152 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17153 ok(SUCCEEDED(hr), "Failed to add dirty rect, 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 todo_wine ok(color_match(color, 0x00ff0000, 1),
17160 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17161 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17162 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17164 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17165 * tracking is supported. */
17166 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17167 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17168 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17169 (IDirect3DBaseTexture9 *)tex_dst2);
17170 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17171 add_dirty_rect_test_draw(device);
17172 color = getPixelColor(device, 320, 240);
17173 ok(color_match(color, 0x0000ff00, 1),
17174 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17175 color = getPixelColor(device, 1, 1);
17176 todo_wine ok(color_match(color, 0x00ff0000, 1),
17177 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17178 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17179 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17181 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17182 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17183 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17184 (IDirect3DBaseTexture9 *)tex_dst2);
17185 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17186 add_dirty_rect_test_draw(device);
17187 color = getPixelColor(device, 1, 1);
17188 ok(color_match(color, 0x0000ff00, 1),
17189 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17191 /* Locks with NO_DIRTY_UPDATE are ignored. */
17192 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17193 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17194 (IDirect3DBaseTexture9 *)tex_dst2);
17195 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17196 add_dirty_rect_test_draw(device);
17197 color = getPixelColor(device, 320, 240);
17198 todo_wine ok(color_match(color, 0x0000ff00, 1),
17199 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17201 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17203 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17204 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17205 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17206 (IDirect3DBaseTexture9 *)tex_dst2);
17207 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17208 add_dirty_rect_test_draw(device);
17209 color = getPixelColor(device, 320, 240);
17210 todo_wine ok(color_match(color, 0x0000ff00, 1),
17211 "Expected color 0x0000ff00, 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 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17216 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17217 (IDirect3DBaseTexture9 *)tex_dst2);
17218 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17219 add_dirty_rect_test_draw(device);
17220 color = getPixelColor(device, 320, 240);
17221 ok(color_match(color, 0x000000ff, 1),
17222 "Expected color 0x000000ff, got 0x%08x.\n", color);
17223 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17224 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17226 /* Maps without either of these flags record a dirty rectangle. */
17227 fill_surface(surface_src_green, 0x00ffffff, 0);
17228 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17229 (IDirect3DBaseTexture9 *)tex_dst2);
17230 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17231 add_dirty_rect_test_draw(device);
17232 color = getPixelColor(device, 320, 240);
17233 ok(color_match(color, 0x00ffffff, 1),
17234 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17235 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17236 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17238 /* Partial LockRect works just like a partial AddDirtyRect call. */
17239 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17240 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17241 texel = locked_rect.pBits;
17242 for (i = 0; i < 64; i++)
17243 texel[i] = 0x00ff00ff;
17244 for (i = 1; i < 64; i++)
17245 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17246 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17247 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17248 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17249 (IDirect3DBaseTexture9 *)tex_dst2);
17250 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17251 add_dirty_rect_test_draw(device);
17252 color = getPixelColor(device, 320, 240);
17253 ok(color_match(color, 0x00ff00ff, 1),
17254 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17255 color = getPixelColor(device, 1, 1);
17256 ok(color_match(color, 0x00ffffff, 1),
17257 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17258 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17259 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17261 fill_surface(surface_src_red, 0x00ff0000, 0);
17262 fill_surface(surface_src_green, 0x0000ff00, 0);
17264 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17265 (IDirect3DBaseTexture9 *)tex_dst1);
17266 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17267 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17268 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17269 add_dirty_rect_test_draw(device);
17270 color = getPixelColor(device, 320, 240);
17271 ok(color_match(color, 0x0000ff00, 1),
17272 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17273 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17274 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17276 /* UpdateSurface ignores the missing dirty marker. */
17277 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17278 (IDirect3DBaseTexture9 *)tex_dst2);
17279 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17280 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17281 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17282 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17283 add_dirty_rect_test_draw(device);
17284 color = getPixelColor(device, 320, 240);
17285 ok(color_match(color, 0x0000ff00, 1),
17286 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17287 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17288 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17290 fill_surface(surface_managed, 0x00ff0000, 0);
17291 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17292 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17293 add_dirty_rect_test_draw(device);
17294 color = getPixelColor(device, 320, 240);
17295 ok(color_match(color, 0x00ff0000, 1),
17296 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17297 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17298 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17300 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17301 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17302 add_dirty_rect_test_draw(device);
17303 color = getPixelColor(device, 320, 240);
17304 ok(color_match(color, 0x00ff0000, 1),
17305 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17306 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17307 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17309 /* AddDirtyRect uploads the new contents.
17310 * Side note, not tested in the test: Partial surface updates work, and two separate
17311 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17312 * untested. */
17313 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17314 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17315 add_dirty_rect_test_draw(device);
17316 color = getPixelColor(device, 320, 240);
17317 ok(color_match(color, 0x0000ff00, 1),
17318 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17319 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17320 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17322 /* So does EvictManagedResources. */
17323 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17324 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17325 hr = IDirect3DDevice9_EvictManagedResources(device);
17326 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17327 add_dirty_rect_test_draw(device);
17328 color = getPixelColor(device, 320, 240);
17329 ok(color_match(color, 0x000000ff, 1),
17330 "Expected color 0x000000ff, got 0x%08x.\n", color);
17331 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17332 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17334 /* AddDirtyRect on a locked texture is allowed. */
17335 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17336 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17337 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17338 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17339 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17340 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17342 /* Redundant AddDirtyRect calls are ok. */
17343 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17344 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17345 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17346 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17348 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17349 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17350 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17351 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17352 IDirect3DSurface9_Release(surface_dst2);
17353 IDirect3DSurface9_Release(surface_managed);
17354 IDirect3DSurface9_Release(surface_src_red);
17355 IDirect3DSurface9_Release(surface_src_green);
17356 IDirect3DTexture9_Release(tex_src_red);
17357 IDirect3DTexture9_Release(tex_src_green);
17358 IDirect3DTexture9_Release(tex_dst1);
17359 IDirect3DTexture9_Release(tex_dst2);
17360 IDirect3DTexture9_Release(tex_managed);
17361 refcount = IDirect3DDevice9_Release(device);
17362 ok(!refcount, "Device has %u references left.\n", refcount);
17363 IDirect3D9_Release(d3d);
17364 DestroyWindow(window);
17367 static void test_per_stage_constant(void)
17369 IDirect3DDevice9 *device;
17370 IDirect3D9 *d3d;
17371 D3DCOLOR color;
17372 ULONG refcount;
17373 D3DCAPS9 caps;
17374 HWND window;
17375 HRESULT hr;
17377 static const struct
17379 struct vec3 position;
17380 D3DCOLOR diffuse;
17382 quad[] =
17384 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17385 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17386 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17387 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17390 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17391 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17392 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17393 ok(!!d3d, "Failed to create a D3D object.\n");
17394 if (!(device = create_device(d3d, window, window, TRUE)))
17396 skip("Failed to create a D3D device, skipping tests.\n");
17397 goto done;
17400 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17401 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17402 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17404 skip("Per-stage constants not supported, skipping tests.\n");
17405 IDirect3DDevice9_Release(device);
17406 goto done;
17409 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17410 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17412 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17414 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17416 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17418 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17421 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17422 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17423 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17424 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17425 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17428 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17430 hr = IDirect3DDevice9_BeginScene(device);
17431 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17433 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17434 hr = IDirect3DDevice9_EndScene(device);
17435 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17437 color = getPixelColor(device, 320, 240);
17438 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17439 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17440 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17442 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17443 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17446 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17448 hr = IDirect3DDevice9_BeginScene(device);
17449 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17450 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17451 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17452 hr = IDirect3DDevice9_EndScene(device);
17453 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17455 color = getPixelColor(device, 320, 240);
17456 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17457 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17458 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17460 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17461 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17464 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17466 hr = IDirect3DDevice9_BeginScene(device);
17467 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17469 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17470 hr = IDirect3DDevice9_EndScene(device);
17471 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17473 color = getPixelColor(device, 320, 240);
17474 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17476 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17478 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17479 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17480 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17481 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17482 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17483 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17486 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17488 hr = IDirect3DDevice9_BeginScene(device);
17489 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17490 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17491 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17492 hr = IDirect3DDevice9_EndScene(device);
17493 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17495 color = getPixelColor(device, 320, 240);
17496 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17497 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17498 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17500 refcount = IDirect3DDevice9_Release(device);
17501 ok(!refcount, "Device has %u references left.\n", refcount);
17502 done:
17503 IDirect3D9_Release(d3d);
17504 DestroyWindow(window);
17507 static void test_3dc_formats(void)
17509 static const char ati1n_data[] =
17511 /* A 4x4 texture with the color component at 50%. */
17512 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17514 static const char ati2n_data[] =
17516 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17517 * 0% second component. Second block is the opposite. */
17518 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17521 static const struct
17523 struct vec3 position;
17524 struct vec2 texcoord;
17526 quads[] =
17528 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17529 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17530 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17531 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17533 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17534 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17535 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17536 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17538 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17539 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17540 static const struct
17542 struct vec2 position;
17543 D3DCOLOR amd_r500;
17544 D3DCOLOR amd_r600;
17545 D3DCOLOR nvidia_old;
17546 D3DCOLOR nvidia_new;
17548 expected_colors[] =
17550 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17551 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17552 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17553 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17555 IDirect3D9 *d3d;
17556 IDirect3DDevice9 *device;
17557 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17558 D3DCAPS9 caps;
17559 D3DLOCKED_RECT rect;
17560 D3DCOLOR color;
17561 ULONG refcount;
17562 HWND window;
17563 HRESULT hr;
17564 unsigned int i;
17566 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17567 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17568 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17569 ok(!!d3d, "Failed to create a D3D object.\n");
17570 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17571 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17573 skip("ATI1N textures are not supported, skipping test.\n");
17574 goto done;
17576 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17577 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17579 skip("ATI2N textures are not supported, skipping test.\n");
17580 goto done;
17582 if (!(device = create_device(d3d, window, window, TRUE)))
17584 skip("Failed to create a D3D device, skipping tests.\n");
17585 goto done;
17587 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17588 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17589 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17591 skip("D3DTA_TEMP not supported, skipping tests.\n");
17592 IDirect3DDevice9_Release(device);
17593 goto done;
17596 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17597 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17598 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17600 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17601 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17602 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17603 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17604 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17606 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17607 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17608 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17610 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17611 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17612 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17613 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17614 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17616 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17617 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17618 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17619 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17620 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17621 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17622 /* The temporary register is initialized to 0. */
17623 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17624 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17625 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17626 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17627 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17628 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17629 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17630 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17631 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17632 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17634 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17635 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17636 hr = IDirect3DDevice9_BeginScene(device);
17637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17638 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17639 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17641 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17642 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17643 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17645 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17646 hr = IDirect3DDevice9_EndScene(device);
17647 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17649 for (i = 0; i < 4; ++i)
17651 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17652 ok (color_match(color, expected_colors[i].amd_r500, 1)
17653 || color_match(color, expected_colors[i].amd_r600, 1)
17654 || color_match(color, expected_colors[i].nvidia_old, 1)
17655 || color_match(color, expected_colors[i].nvidia_new, 1),
17656 "Got unexpected color 0x%08x, case %u.\n", color, i);
17659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17660 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17661 IDirect3DTexture9_Release(ati2n_texture);
17662 IDirect3DTexture9_Release(ati1n_texture);
17663 refcount = IDirect3DDevice9_Release(device);
17664 ok(!refcount, "Device has %u references left.\n", refcount);
17666 done:
17667 IDirect3D9_Release(d3d);
17668 DestroyWindow(window);
17671 static void test_fog_interpolation(void)
17673 HRESULT hr;
17674 IDirect3DDevice9 *device;
17675 IDirect3D9 *d3d;
17676 ULONG refcount;
17677 HWND window;
17678 D3DCOLOR color;
17679 static const struct
17681 struct vec3 position;
17682 D3DCOLOR diffuse;
17683 D3DCOLOR specular;
17685 quad[] =
17687 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
17688 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
17689 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
17690 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
17692 union
17694 DWORD d;
17695 float f;
17696 } conv;
17697 unsigned int i;
17698 static const struct
17700 D3DFOGMODE vfog, tfog;
17701 D3DSHADEMODE shade;
17702 D3DCOLOR middle_color;
17703 BOOL todo;
17705 tests[] =
17707 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
17708 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
17709 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
17710 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
17711 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17712 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17713 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17714 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17716 static const D3DMATRIX ident_mat =
17718 1.0f, 0.0f, 0.0f, 0.0f,
17719 0.0f, 1.0f, 0.0f, 0.0f,
17720 0.0f, 0.0f, 1.0f, 0.0f,
17721 0.0f, 0.0f, 0.0f, 1.0f
17722 }}};
17723 D3DCAPS9 caps;
17725 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17726 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17727 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17728 ok(!!d3d, "Failed to create a D3D object.\n");
17730 if (!(device = create_device(d3d, window, window, TRUE)))
17732 skip("Failed to create a D3D device, skipping tests.\n");
17733 IDirect3D9_Release(d3d);
17734 DestroyWindow(window);
17735 return;
17738 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17739 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17740 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17741 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
17743 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
17744 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17746 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
17748 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17749 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17750 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17752 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17753 conv.f = 5.0;
17754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
17755 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17757 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17758 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17759 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
17760 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
17762 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17764 /* Some of the tests seem to depend on the projection matrix explicitly
17765 * being set to an identity matrix, even though that's the default.
17766 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
17767 * the drivers seem to use a static z = 1.0 input for the fog equation.
17768 * The input value is independent of the actual z and w component of
17769 * the vertex position. */
17770 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
17771 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17773 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17775 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
17776 continue;
17778 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
17779 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
17782 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
17784 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
17786 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17787 hr = IDirect3DDevice9_BeginScene(device);
17788 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17790 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17791 hr = IDirect3DDevice9_EndScene(device);
17792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17794 color = getPixelColor(device, 0, 240);
17795 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
17796 color = getPixelColor(device, 320, 240);
17797 if (tests[i].todo)
17798 todo_wine ok(color_match(color, tests[i].middle_color, 2),
17799 "Got unexpected color 0x%08x, case %u.\n", color, i);
17800 else
17801 ok(color_match(color, tests[i].middle_color, 2),
17802 "Got unexpected color 0x%08x, case %u.\n", color, i);
17803 color = getPixelColor(device, 639, 240);
17804 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
17805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17806 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17809 refcount = IDirect3DDevice9_Release(device);
17810 ok(!refcount, "Device has %u references left.\n", refcount);
17811 IDirect3D9_Release(d3d);
17812 DestroyWindow(window);
17815 static void test_negative_fixedfunction_fog(void)
17817 HRESULT hr;
17818 IDirect3DDevice9 *device;
17819 IDirect3D9 *d3d;
17820 ULONG refcount;
17821 HWND window;
17822 D3DCOLOR color;
17823 static const struct
17825 struct vec3 position;
17826 D3DCOLOR diffuse;
17828 quad[] =
17830 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
17831 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
17832 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
17833 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
17835 static const struct
17837 struct vec4 position;
17838 D3DCOLOR diffuse;
17840 tquad[] =
17842 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
17843 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
17844 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
17845 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
17847 unsigned int i;
17848 static const D3DMATRIX zero =
17850 1.0f, 0.0f, 0.0f, 0.0f,
17851 0.0f, 1.0f, 0.0f, 0.0f,
17852 0.0f, 0.0f, 0.0f, 0.0f,
17853 0.0f, 0.0f, 0.0f, 1.0f
17854 }}};
17855 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
17856 * have an effect on RHW draws. */
17857 static const D3DMATRIX identity =
17859 1.0f, 0.0f, 0.0f, 0.0f,
17860 0.0f, 1.0f, 0.0f, 0.0f,
17861 0.0f, 0.0f, 1.0f, 0.0f,
17862 0.0f, 0.0f, 0.0f, 1.0f
17863 }}};
17864 static const struct
17866 DWORD pos_type;
17867 const void *quad;
17868 size_t stride;
17869 const D3DMATRIX *matrix;
17870 union
17872 float f;
17873 DWORD d;
17874 } start, end;
17875 D3DFOGMODE vfog, tfog;
17876 DWORD color, color_broken, color_broken2;
17878 tests[] =
17880 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
17882 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
17883 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
17884 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
17885 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
17886 * parameters to 0.0 and 1.0 in the table fog case. */
17887 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
17888 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
17889 /* test_fog_interpolation shows that vertex fog evaluates the fog
17890 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
17891 * that the abs happens before the fog equation is evaluated.
17893 * Vertex fog abs() behavior is the same on all GPUs. */
17894 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
17895 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
17896 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
17897 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
17898 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
17899 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
17901 D3DCAPS9 caps;
17903 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17904 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17905 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17906 ok(!!d3d, "Failed to create a D3D object.\n");
17908 if (!(device = create_device(d3d, window, window, TRUE)))
17910 skip("Failed to create a D3D device, skipping tests.\n");
17911 IDirect3D9_Release(d3d);
17912 DestroyWindow(window);
17913 return;
17916 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17917 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17918 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17919 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
17921 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17922 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17924 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17926 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17928 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
17930 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
17932 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17934 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
17935 continue;
17937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
17938 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17940 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
17941 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17942 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
17943 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
17945 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
17947 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
17949 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
17951 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17953 hr = IDirect3DDevice9_BeginScene(device);
17954 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
17956 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17957 hr = IDirect3DDevice9_EndScene(device);
17958 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17960 color = getPixelColor(device, 320, 240);
17961 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
17962 || broken(color_match(color, tests[i].color_broken2, 2)),
17963 "Got unexpected color 0x%08x, case %u.\n", color, i);
17964 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17965 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17968 refcount = IDirect3DDevice9_Release(device);
17969 ok(!refcount, "Device has %u references left.\n", refcount);
17970 IDirect3D9_Release(d3d);
17971 DestroyWindow(window);
17974 static void test_position_index(void)
17976 static const D3DVERTEXELEMENT9 decl_elements[] =
17978 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
17979 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
17980 D3DDECL_END()
17982 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
17983 * but works on Nvidia.
17984 * MSDN is not consistent on this point. */
17985 static const DWORD vs_code[] =
17987 0xfffe0300, /* vs_3_0 */
17988 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17989 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
17990 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
17991 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
17992 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
17993 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
17994 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
17995 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
17996 0x0000ffff /* end */
17998 static const DWORD vs_code_2[] =
18000 0xfffe0300, /* vs_3_0 */
18001 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18002 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18003 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18004 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18005 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18006 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18007 0x0000ffff /* end */
18009 static const DWORD ps_code[] =
18011 0xffff0300, /* ps_3_0 */
18012 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18013 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18014 0x0000ffff /* end */
18016 static const DWORD ps_code_2[] =
18018 0xffff0300, /* ps_3_0 */
18019 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18020 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18021 0x0000ffff /* end */
18023 /* This one is considered invalid by the native shader assembler. */
18024 static const DWORD ps_code_bad[] =
18026 0xffff0300, /* ps_3_0 */
18027 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18028 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18029 0x0000ffff /* end */
18031 static const struct
18033 struct vec3 position;
18034 struct vec3 position1;
18036 quad[] =
18038 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18039 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18040 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18041 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18043 static const struct
18045 struct vec2 position;
18046 D3DCOLOR expected_color;
18047 D3DCOLOR broken_color;
18049 expected_colors[] =
18051 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18052 {{240, 240}, 0x009f6000, 0x00ff00ff},
18053 {{400, 240}, 0x00609f00, 0x00ff00ff},
18054 {{560, 240}, 0x0020df00, 0x00ff00ff},
18056 IDirect3D9 *d3d;
18057 IDirect3DDevice9 *device;
18058 IDirect3DVertexDeclaration9 *vertex_declaration;
18059 IDirect3DVertexShader9 *vs, *vs2;
18060 IDirect3DPixelShader9 *ps, *ps2;
18061 D3DCAPS9 caps;
18062 D3DCOLOR color;
18063 ULONG refcount;
18064 HWND window;
18065 HRESULT hr;
18066 unsigned int i;
18068 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18069 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18070 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18071 ok(!!d3d, "Failed to create a D3D object.\n");
18072 if (!(device = create_device(d3d, window, window, TRUE)))
18074 skip("Failed to create a D3D device, skipping tests.\n");
18075 goto done;
18078 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18079 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18080 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18081 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18083 skip("Shader model 3.0 unsupported, skipping tests.\n");
18084 IDirect3DDevice9_Release(device);
18085 goto done;
18088 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18089 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18091 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18092 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18094 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18095 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18096 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18097 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18099 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18100 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18102 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18103 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18105 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18106 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18107 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18108 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18110 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18111 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18113 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18114 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18115 hr = IDirect3DDevice9_BeginScene(device);
18116 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18118 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18119 hr = IDirect3DDevice9_EndScene(device);
18120 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18122 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18124 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18125 ok (color_match(color, expected_colors[i].expected_color, 1)
18126 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18127 "Got unexpected color 0x%08x, case %u.\n", color, i);
18130 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18131 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18134 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18135 hr = IDirect3DDevice9_BeginScene(device);
18136 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18138 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18139 hr = IDirect3DDevice9_EndScene(device);
18140 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18142 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18144 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18145 ok (color_match(color, expected_colors[i].expected_color, 1)
18146 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18147 "Got unexpected color 0x%08x, case %u.\n", color, i);
18150 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18151 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18153 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18154 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18155 hr = IDirect3DDevice9_BeginScene(device);
18156 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18158 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18159 hr = IDirect3DDevice9_EndScene(device);
18160 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18162 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18164 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18165 ok (color_match(color, expected_colors[i].expected_color, 1),
18166 "Got unexpected color 0x%08x, case %u.\n", color, i);
18169 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18170 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18172 IDirect3DPixelShader9_Release(ps2);
18173 IDirect3DPixelShader9_Release(ps);
18174 IDirect3DVertexShader9_Release(vs2);
18175 IDirect3DVertexShader9_Release(vs);
18176 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18177 refcount = IDirect3DDevice9_Release(device);
18178 ok(!refcount, "Device has %u references left.\n", refcount);
18180 done:
18181 IDirect3D9_Release(d3d);
18182 DestroyWindow(window);
18185 static void test_table_fog_zw(void)
18187 HRESULT hr;
18188 IDirect3DDevice9 *device;
18189 IDirect3D9 *d3d;
18190 ULONG refcount;
18191 HWND window;
18192 D3DCOLOR color;
18193 D3DCAPS9 caps;
18194 static struct
18196 struct vec4 position;
18197 D3DCOLOR diffuse;
18199 quad[] =
18201 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18202 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18203 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18204 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18206 static const D3DMATRIX identity =
18208 1.0f, 0.0f, 0.0f, 0.0f,
18209 0.0f, 1.0f, 0.0f, 0.0f,
18210 0.0f, 0.0f, 1.0f, 0.0f,
18211 0.0f, 0.0f, 0.0f, 1.0f
18212 }}};
18213 static const struct
18215 float z, w;
18216 D3DZBUFFERTYPE z_test;
18217 D3DCOLOR color;
18219 tests[] =
18221 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18222 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18223 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18224 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18225 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18226 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18227 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18228 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18230 unsigned int i;
18232 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18233 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18234 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18235 ok(!!d3d, "Failed to create a D3D object.\n");
18237 if (!(device = create_device(d3d, window, window, TRUE)))
18239 skip("Failed to create a D3D device, skipping tests.\n");
18240 IDirect3D9_Release(d3d);
18241 DestroyWindow(window);
18242 return;
18245 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18246 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18247 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18249 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18250 goto done;
18253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18254 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18256 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18258 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18260 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18261 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18262 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18263 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18265 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18266 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18267 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18269 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18271 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18272 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18274 quad[0].position.z = tests[i].z;
18275 quad[1].position.z = tests[i].z;
18276 quad[2].position.z = tests[i].z;
18277 quad[3].position.z = tests[i].z;
18278 quad[0].position.w = tests[i].w;
18279 quad[1].position.w = tests[i].w;
18280 quad[2].position.w = tests[i].w;
18281 quad[3].position.w = tests[i].w;
18282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18283 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18285 hr = IDirect3DDevice9_BeginScene(device);
18286 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18287 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18288 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18289 hr = IDirect3DDevice9_EndScene(device);
18290 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18292 color = getPixelColor(device, 320, 240);
18293 ok(color_match(color, tests[i].color, 2),
18294 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18295 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18296 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18299 done:
18300 refcount = IDirect3DDevice9_Release(device);
18301 ok(!refcount, "Device has %u references left.\n", refcount);
18302 IDirect3D9_Release(d3d);
18303 DestroyWindow(window);
18306 static void test_signed_formats(void)
18308 IDirect3DDevice9 *device;
18309 HWND window;
18310 HRESULT hr;
18311 unsigned int i, j, x, y;
18312 IDirect3DTexture9 *texture, *texture_sysmem;
18313 IDirect3DSurface9 *src_surface, *dst_surface;
18314 D3DLOCKED_RECT locked_rect;
18315 IDirect3DPixelShader9 *shader, *shader_alpha;
18316 IDirect3D9 *d3d;
18317 D3DCOLOR color;
18318 D3DCAPS9 caps;
18319 ULONG refcount;
18321 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18322 * to the other formats because L6V5U5 is the lowest precision format.
18323 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18324 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18325 * Some other intermediate values are tested too. The input value -15
18326 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18327 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18328 * using the expected output data the 8 bit and 16 bit values in V8U8
18329 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18330 * -1, 1 and -127 are not tested in V8U8.
18332 * 8 bit specific values like -127 are tested in the Q channel of
18333 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18334 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18335 * -128. The difference between using -127 or -128 as the lowest
18336 * possible value gets lost in the slop of 1 though. */
18337 static const USHORT content_v8u8[4][4] =
18339 {0x0000, 0x7f7f, 0x8880, 0x0000},
18340 {0x0080, 0x8000, 0x7f00, 0x007f},
18341 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18342 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18344 static const DWORD content_v16u16[4][4] =
18346 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18347 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18348 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18349 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18351 static const DWORD content_q8w8v8u8[4][4] =
18353 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18354 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18355 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18356 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18358 static const DWORD content_x8l8v8u8[4][4] =
18360 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18361 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18362 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18363 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18365 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18366 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18367 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18368 * though.
18370 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18371 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18372 * the proper results of -6 and -2.
18374 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18375 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18376 * is 0x84 instead of 0x80. */
18377 static const USHORT content_l6v5u5[4][4] =
18379 {0x0000, 0xfdef, 0x0230, 0xfc00},
18380 {0x0010, 0x0200, 0x01e0, 0x000f},
18381 {0x4067, 0x53b9, 0x0421, 0xffff},
18382 {0x8108, 0x0318, 0xc28c, 0x909c},
18384 static const struct
18386 D3DFORMAT format;
18387 const char *name;
18388 const void *content;
18389 SIZE_T pixel_size;
18390 BOOL blue, alpha;
18391 unsigned int slop, slop_broken, alpha_broken;
18393 formats[] =
18395 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18396 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18397 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18398 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18399 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18401 static const struct
18403 D3DPOOL pool;
18404 UINT width;
18405 RECT src_rect;
18406 POINT dst_point;
18408 tests[] =
18410 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18411 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18412 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18413 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18415 static const DWORD shader_code[] =
18417 0xffff0101, /* ps_1_1 */
18418 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18419 0x00000042, 0xb00f0000, /* tex t0 */
18420 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18421 0x0000ffff /* end */
18423 static const DWORD shader_code_alpha[] =
18425 /* The idea of this shader is to replicate the alpha value in .rg, and set
18426 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18427 0xffff0101, /* ps_1_1 */
18428 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18429 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18430 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18431 0x00000042, 0xb00f0000, /* tex t0 */
18432 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18433 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18434 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18435 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18436 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18437 0x0000ffff /* end */
18439 static const struct
18441 struct vec3 position;
18442 struct vec2 texcrd;
18444 quad[] =
18446 /* Flip the y coordinate to make the input and
18447 * output arrays easier to compare. */
18448 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18449 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18450 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18451 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18453 static const D3DCOLOR expected_alpha[4][4] =
18455 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18456 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18457 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18458 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18460 static const BOOL alpha_broken[4][4] =
18462 {FALSE, FALSE, FALSE, FALSE},
18463 {FALSE, FALSE, FALSE, FALSE},
18464 {FALSE, FALSE, FALSE, TRUE },
18465 {FALSE, FALSE, FALSE, FALSE},
18467 static const D3DCOLOR expected_colors[4][4] =
18469 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18470 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18471 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18472 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18474 static const D3DCOLOR expected_colors2[4][4] =
18476 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18477 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18478 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18479 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18481 static const D3DCOLOR expected_colors3[4] =
18483 0x00018080,
18484 0x00ba98a0,
18485 0x00ba98a0,
18486 0x00c3c3c0,
18488 D3DCOLOR expected_color;
18490 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18491 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18492 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18493 ok(!!d3d, "Failed to create a D3D object.\n");
18495 if (!(device = create_device(d3d, window, window, TRUE)))
18497 skip("Failed to create a D3D device, skipping tests.\n");
18498 IDirect3D9_Release(d3d);
18499 DestroyWindow(window);
18500 return;
18503 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18504 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18506 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18508 skip("Pixel shaders not supported, skipping converted format test.\n");
18509 goto done;
18512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18513 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18514 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18515 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18516 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18517 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18518 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18519 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18521 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18523 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18524 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18525 if (FAILED(hr))
18527 skip("Format %s not supported, skipping.\n", formats[i].name);
18528 continue;
18531 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18533 texture_sysmem = NULL;
18534 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18535 formats[i].format, tests[j].pool, &texture, NULL);
18536 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18538 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18539 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18540 for (y = 0; y < 4; y++)
18542 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18543 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18544 tests[j].width * formats[i].pixel_size);
18546 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18547 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18549 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18551 texture_sysmem = texture;
18552 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18553 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18554 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18556 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18557 (IDirect3DBaseTexture9 *)texture);
18558 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18561 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18562 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18563 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18564 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18566 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18567 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18568 hr = IDirect3DDevice9_BeginScene(device);
18569 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18570 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18571 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18572 hr = IDirect3DDevice9_EndScene(device);
18573 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18575 for (y = 0; y < 4; y++)
18577 for (x = 0; x < tests[j].width; x++)
18579 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18580 if (formats[i].alpha)
18581 expected_color = expected_alpha[y][x];
18582 else
18583 expected_color = 0x00ffff00;
18585 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18586 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18587 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18588 expected_color, color, formats[i].name, x, y);
18591 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18592 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18594 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18595 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18598 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18599 hr = IDirect3DDevice9_BeginScene(device);
18600 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18601 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18602 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18603 hr = IDirect3DDevice9_EndScene(device);
18604 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18606 for (y = 0; y < 4; y++)
18608 for (x = 0; x < tests[j].width; x++)
18610 expected_color = expected_colors[y][x];
18611 if (!formats[i].blue)
18612 expected_color |= 0x000000ff;
18614 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18615 ok(color_match(color, expected_color, formats[i].slop)
18616 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18617 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18618 expected_color, color, formats[i].name, x, y);
18621 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18622 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18624 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18626 IDirect3DTexture9_Release(texture);
18627 continue;
18630 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18631 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18632 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18633 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18635 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18636 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18637 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18639 IDirect3DSurface9_Release(dst_surface);
18640 IDirect3DSurface9_Release(src_surface);
18642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18643 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18644 hr = IDirect3DDevice9_BeginScene(device);
18645 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18647 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18648 hr = IDirect3DDevice9_EndScene(device);
18649 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18651 for (y = 0; y < 4; y++)
18653 for (x = 0; x < tests[j].width; x++)
18655 if (tests[j].width == 4)
18656 expected_color = expected_colors2[y][x];
18657 else
18658 expected_color = expected_colors3[y];
18660 if (!formats[i].blue)
18661 expected_color |= 0x000000ff;
18663 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18664 ok(color_match(color, expected_color, formats[i].slop)
18665 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18666 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18667 expected_color, color, formats[i].name, x, y);
18670 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18671 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18673 IDirect3DTexture9_Release(texture_sysmem);
18674 IDirect3DTexture9_Release(texture);
18678 IDirect3DPixelShader9_Release(shader);
18679 IDirect3DPixelShader9_Release(shader_alpha);
18681 done:
18682 refcount = IDirect3DDevice9_Release(device);
18683 ok(!refcount, "Device has %u references left.\n", refcount);
18684 IDirect3D9_Release(d3d);
18685 DestroyWindow(window);
18688 static void test_multisample_mismatch(void)
18690 IDirect3DDevice9 *device;
18691 IDirect3D9 *d3d;
18692 HWND window;
18693 HRESULT hr;
18694 D3DCOLOR color;
18695 ULONG refcount;
18696 IDirect3DSurface9 *rt, *rt_multi, *ds;
18697 static const struct
18699 struct vec3 position;
18700 DWORD color;
18702 quad[] =
18704 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
18705 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
18706 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
18707 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
18710 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18711 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18712 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18713 ok(!!d3d, "Failed to create a D3D object.\n");
18714 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18715 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18717 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
18718 IDirect3D9_Release(d3d);
18719 return;
18721 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18722 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18724 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
18725 IDirect3D9_Release(d3d);
18726 return;
18729 if (!(device = create_device(d3d, window, window, TRUE)))
18731 skip("Failed to create a D3D device, skipping tests.\n");
18732 IDirect3D9_Release(d3d);
18733 DestroyWindow(window);
18734 return;
18737 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18738 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
18739 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
18741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
18742 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18744 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18745 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
18746 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
18747 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
18748 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18749 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18752 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18753 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18754 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18756 /* Clear with incompatible buffers. Partial and combined clears. */
18757 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18758 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18759 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
18760 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
18762 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18764 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
18765 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18766 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18767 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18768 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18769 color = getPixelColor(device, 320, 240);
18770 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18771 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18772 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18774 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
18775 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
18776 * the Z only clear case nor in the combined clear case. */
18777 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18778 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18779 hr = IDirect3DDevice9_BeginScene(device);
18780 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18781 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18782 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18783 hr = IDirect3DDevice9_EndScene(device);
18784 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18785 color = getPixelColor(device, 62, 240);
18786 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18787 color = getPixelColor(device, 64, 240);
18788 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18789 "Got unexpected color 0x%08x.\n", color);
18790 color = getPixelColor(device, 318, 240);
18791 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18792 "Got unexpected color 0x%08x.\n", color);
18793 color = getPixelColor(device, 322, 240);
18794 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18796 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18798 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
18799 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
18800 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
18801 * show up either. Only test the ZENABLE = FALSE case for now. */
18802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18803 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18804 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18805 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18806 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18807 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18808 hr = IDirect3DDevice9_BeginScene(device);
18809 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18810 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18811 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18812 hr = IDirect3DDevice9_EndScene(device);
18813 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18815 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18816 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18817 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18818 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18819 color = getPixelColor(device, 320, 240);
18820 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18821 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18822 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18824 IDirect3DSurface9_Release(ds);
18826 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
18827 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
18828 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
18829 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
18830 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
18831 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18832 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
18833 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18834 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
18836 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18838 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18839 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18841 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18842 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
18843 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18844 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
18845 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18847 color = getPixelColor(device, 320, 240);
18848 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18849 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18850 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18852 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18853 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18855 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18856 hr = IDirect3DDevice9_BeginScene(device);
18857 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18858 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18859 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18860 hr = IDirect3DDevice9_EndScene(device);
18861 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18863 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18864 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18865 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18866 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18867 color = getPixelColor(device, 62, 240);
18868 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18869 color = getPixelColor(device, 318, 240);
18870 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18871 "Got unexpected color 0x%08x.\n", color);
18872 color = getPixelColor(device, 322, 240);
18873 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
18874 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18875 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18877 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
18878 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
18879 * is disabled. Again only test the ZENABLE = FALSE case. */
18880 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18881 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18882 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18883 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18884 hr = IDirect3DDevice9_BeginScene(device);
18885 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18887 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18888 hr = IDirect3DDevice9_EndScene(device);
18889 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18890 color = getPixelColor(device, 320, 240);
18891 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18892 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18893 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18895 IDirect3DSurface9_Release(rt);
18896 IDirect3DSurface9_Release(ds);
18897 IDirect3DSurface9_Release(rt_multi);
18899 refcount = IDirect3DDevice9_Release(device);
18900 ok(!refcount, "Device has %u references left.\n", refcount);
18901 IDirect3D9_Release(d3d);
18902 DestroyWindow(window);
18905 static void test_texcoordindex(void)
18907 static const D3DMATRIX mat =
18909 1.0f, 0.0f, 0.0f, 0.0f,
18910 0.0f, 0.0f, 0.0f, 0.0f,
18911 0.0f, 0.0f, 0.0f, 0.0f,
18912 0.0f, 0.0f, 0.0f, 0.0f,
18913 }}};
18914 static const struct
18916 struct vec3 pos;
18917 struct vec2 texcoord1;
18918 struct vec2 texcoord2;
18919 struct vec2 texcoord3;
18921 quad[] =
18923 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
18924 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
18925 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
18926 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
18928 IDirect3DDevice9 *device;
18929 IDirect3D9 *d3d9;
18930 HWND window;
18931 HRESULT hr;
18932 IDirect3DTexture9 *texture1, *texture2;
18933 D3DLOCKED_RECT locked_rect;
18934 ULONG refcount;
18935 D3DCOLOR color;
18936 DWORD *ptr;
18938 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18939 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18940 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
18941 ok(!!d3d9, "Failed to create a D3D object.\n");
18942 if (!(device = create_device(d3d9, window, window, TRUE)))
18944 skip("Failed to create a D3D device, skipping tests.\n");
18945 IDirect3D9_Release(d3d9);
18946 DestroyWindow(window);
18947 return;
18950 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
18951 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18952 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
18953 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18955 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
18956 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18957 ptr = locked_rect.pBits;
18958 ptr[0] = 0xff000000;
18959 ptr[1] = 0xff00ff00;
18960 ptr[2] = 0xff0000ff;
18961 ptr[3] = 0xff00ffff;
18962 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
18963 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18965 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
18966 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18967 ptr = locked_rect.pBits;
18968 ptr[0] = 0xff000000;
18969 ptr[1] = 0xff0000ff;
18970 ptr[2] = 0xffff0000;
18971 ptr[3] = 0xffff00ff;
18972 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
18973 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18975 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
18976 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18977 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
18978 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
18980 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18982 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
18983 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18984 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18985 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18986 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18987 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
18988 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18989 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18990 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18991 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
18992 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18993 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
18994 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18996 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
18997 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
18998 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
18999 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19001 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19002 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19004 hr = IDirect3DDevice9_BeginScene(device);
19005 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19008 hr = IDirect3DDevice9_EndScene(device);
19009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19011 color = getPixelColor(device, 160, 120);
19012 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19013 color = getPixelColor(device, 480, 120);
19014 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19015 color = getPixelColor(device, 160, 360);
19016 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19017 color = getPixelColor(device, 480, 360);
19018 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19020 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19021 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19022 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19023 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19025 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19026 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19028 hr = IDirect3DDevice9_BeginScene(device);
19029 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19031 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19032 hr = IDirect3DDevice9_EndScene(device);
19033 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19035 color = getPixelColor(device, 160, 120);
19036 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19037 color = getPixelColor(device, 480, 120);
19038 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19039 color = getPixelColor(device, 160, 360);
19040 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19041 color = getPixelColor(device, 480, 360);
19042 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19044 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19045 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19046 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19047 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19049 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19050 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19052 hr = IDirect3DDevice9_BeginScene(device);
19053 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19055 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19056 hr = IDirect3DDevice9_EndScene(device);
19057 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19059 color = getPixelColor(device, 160, 120);
19060 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19061 color = getPixelColor(device, 480, 120);
19062 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19063 color = getPixelColor(device, 160, 360);
19064 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19065 color = getPixelColor(device, 480, 360);
19066 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19068 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19069 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19071 IDirect3DTexture9_Release(texture1);
19072 IDirect3DTexture9_Release(texture2);
19074 refcount = IDirect3DDevice9_Release(device);
19075 ok(!refcount, "Device has %u references left.\n", refcount);
19076 IDirect3D9_Release(d3d9);
19077 DestroyWindow(window);
19080 static void test_vertex_blending(void)
19082 IDirect3DDevice9 *device;
19083 IDirect3D9 *d3d;
19084 D3DCAPS9 caps;
19085 D3DCOLOR color;
19086 ULONG refcount;
19087 HWND window;
19088 HRESULT hr;
19089 int i;
19091 static const D3DMATRIX view_mat =
19093 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19094 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19095 0.0f, 0.0f, 1.0f, 0.0f,
19096 0.0f, 0.0f, 0.0f, 1.0f
19097 }}},
19098 upper_left =
19100 1.0f, 0.0f, 0.0f, 0.0f,
19101 0.0f, 1.0f, 0.0f, 0.0f,
19102 0.0f, 0.0f, 1.0f, 0.0f,
19103 -4.0f, 4.0f, 0.0f, 1.0f
19104 }}},
19105 lower_left =
19107 1.0f, 0.0f, 0.0f, 0.0f,
19108 0.0f, 1.0f, 0.0f, 0.0f,
19109 0.0f, 0.0f, 1.0f, 0.0f,
19110 -4.0f, -4.0f, 0.0f, 1.0f
19111 }}},
19112 upper_right =
19114 1.0f, 0.0f, 0.0f, 0.0f,
19115 0.0f, 1.0f, 0.0f, 0.0f,
19116 0.0f, 0.0f, 1.0f, 0.0f,
19117 4.0f, 4.0f, 0.0f, 1.0f
19118 }}},
19119 lower_right =
19121 1.0f, 0.0f, 0.0f, 0.0f,
19122 0.0f, 1.0f, 0.0f, 0.0f,
19123 0.0f, 0.0f, 1.0f, 0.0f,
19124 4.0f, -4.0f, 0.0f, 1.0f
19125 }}};
19127 static const POINT quad_upper_right_points[] =
19129 {576, 48}, {-1, -1},
19131 quad_upper_right_empty_points[] =
19133 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19135 quad_center_points[] =
19137 {320, 240}, {-1, -1}
19139 quad_center_empty_points[] =
19141 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19143 quad_upper_center_points[] =
19145 {320, 48}, {-1, -1}
19147 quad_upper_center_empty_points[] =
19149 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19151 quad_fullscreen_points[] =
19153 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19155 quad_fullscreen_empty_points[] =
19157 {-1, -1}
19160 static const struct
19162 struct
19164 struct vec3 position;
19165 struct vec3 blendweights;
19167 vertex_data[4];
19168 const POINT *quad_points;
19169 const POINT *empty_points;
19171 tests[] =
19173 /* upper right */
19175 {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19176 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19177 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19178 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}},
19179 quad_upper_right_points, quad_upper_right_empty_points
19181 /* center */
19183 {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19184 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19185 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19186 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}},
19187 quad_center_points, quad_center_empty_points
19189 /* upper center */
19191 {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19192 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19193 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19194 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}},
19195 quad_upper_center_points, quad_upper_center_empty_points
19197 /* full screen */
19199 {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19200 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19201 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19202 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}},
19203 quad_fullscreen_points, quad_fullscreen_empty_points
19207 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19208 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19209 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19210 ok(!!d3d, "Failed to create a D3D object.\n");
19211 if (!(device = create_device(d3d, window, window, TRUE)))
19213 skip("Failed to create a D3D device, skipping tests.\n");
19214 goto done;
19217 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19218 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19219 if (caps.MaxVertexBlendMatrices < 4)
19221 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19222 IDirect3DDevice9_Release(device);
19223 goto done;
19226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19229 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19230 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19232 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19233 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19234 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19235 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19236 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19237 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19238 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19239 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19242 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19244 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19246 const POINT *point;
19248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19249 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19251 hr = IDirect3DDevice9_BeginScene(device);
19252 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19254 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB3);
19255 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data, 6 * sizeof(float));
19258 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19260 hr = IDirect3DDevice9_EndScene(device);
19261 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19264 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
19266 point = tests[i].quad_points;
19267 while (point->x != -1 && point->y != -1)
19269 color = getPixelColor(device, point->x, point->y);
19270 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19271 ++point;
19274 point = tests[i].empty_points;
19275 while (point->x != -1 && point->y != -1)
19277 color = getPixelColor(device, point->x, point->y);
19278 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19279 ++point;
19283 refcount = IDirect3DDevice9_Release(device);
19284 ok(!refcount, "Device has %u references left.\n", refcount);
19286 done:
19287 IDirect3D9_Release(d3d);
19288 DestroyWindow(window);
19291 static void test_updatetexture(void)
19293 IDirect3DDevice9 *device;
19294 IDirect3D9 *d3d9;
19295 HWND window;
19296 HRESULT hr;
19297 IDirect3DBaseTexture9 *src, *dst;
19298 unsigned int t, i, f, l, x, y, z;
19299 D3DLOCKED_RECT locked_rect;
19300 D3DLOCKED_BOX locked_box;
19301 ULONG refcount;
19302 D3DCAPS9 caps;
19303 D3DCOLOR color;
19304 BOOL ati2n_supported, do_visual_test;
19305 static const struct
19307 struct vec3 pos;
19308 struct vec2 texcoord;
19310 quad[] =
19312 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19313 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19314 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19315 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19317 static const struct
19319 struct vec3 pos;
19320 struct vec3 texcoord;
19322 quad_cube_tex[] =
19324 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19325 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19326 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19327 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19329 static const struct
19331 UINT src_width, src_height;
19332 UINT dst_width, dst_height;
19333 UINT src_levels, dst_levels;
19334 D3DFORMAT src_format, dst_format;
19335 BOOL broken;
19337 tests[] =
19339 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19340 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19341 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19342 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19343 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19344 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19345 /* The WARP renderer doesn't handle these cases correctly. */
19346 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19347 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19348 /* Not clear what happens here on Windows, it doesn't make much sense
19349 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19350 * one or something like that). */
19351 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19352 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19353 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19354 /* This one causes weird behavior on Windows (it probably writes out
19355 * of the texture memory). */
19356 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19357 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19358 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19359 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19360 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19361 /* The data is converted correctly on AMD, on Nvidia nothing happens
19362 * (it draws a black quad). */
19363 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19364 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19365 * a 32 bit float on Nvidia (specifically the tested value becomes a
19366 * very small float number which we get as 0 in the test). */
19367 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19368 /* This one doesn't seem to give the expected results on AMD. */
19369 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19370 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19371 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19372 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19374 static const struct
19376 D3DRESOURCETYPE type;
19377 DWORD fvf;
19378 const void *quad;
19379 unsigned int vertex_size;
19380 DWORD cap;
19381 const char *name;
19383 texture_types[] =
19385 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19386 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19388 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19389 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19391 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19392 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19395 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19396 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19397 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19398 ok(!!d3d9, "Failed to create a D3D object.\n");
19399 if (!(device = create_device(d3d9, window, window, TRUE)))
19401 skip("Failed to create a D3D device, skipping tests.\n");
19402 IDirect3D9_Release(d3d9);
19403 DestroyWindow(window);
19404 return;
19407 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19408 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19410 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19411 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19412 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19413 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19414 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19415 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19416 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19417 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19419 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19421 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19422 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19423 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19425 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19427 if (!(caps.TextureCaps & texture_types[t].cap))
19429 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19430 continue;
19433 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19434 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19436 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19437 ati2n_supported = FALSE;
19439 else
19441 ati2n_supported = TRUE;
19444 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19445 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19447 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19449 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19450 continue;
19452 switch (texture_types[t].type)
19454 case D3DRTYPE_TEXTURE:
19455 hr = IDirect3DDevice9_CreateTexture(device,
19456 tests[i].src_width, tests[i].src_height,
19457 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19458 (IDirect3DTexture9 **)&src, NULL);
19459 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19460 hr = IDirect3DDevice9_CreateTexture(device,
19461 tests[i].dst_width, tests[i].dst_height,
19462 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19463 (IDirect3DTexture9 **)&dst, NULL);
19464 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19465 break;
19466 case D3DRTYPE_CUBETEXTURE:
19467 hr = IDirect3DDevice9_CreateCubeTexture(device,
19468 tests[i].src_width,
19469 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19470 (IDirect3DCubeTexture9 **)&src, NULL);
19471 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19472 hr = IDirect3DDevice9_CreateCubeTexture(device,
19473 tests[i].dst_width,
19474 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19475 (IDirect3DCubeTexture9 **)&dst, NULL);
19476 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19477 break;
19478 case D3DRTYPE_VOLUMETEXTURE:
19479 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19480 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19481 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19482 (IDirect3DVolumeTexture9 **)&src, NULL);
19483 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19484 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19485 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19486 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19487 (IDirect3DVolumeTexture9 **)&dst, NULL);
19488 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19489 break;
19490 default:
19491 trace("Unexpected resource type.\n");
19494 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19495 * give a different (and unlikely to be useful) result. */
19496 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19497 && tests[i].src_levels != 0
19498 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19499 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19501 if (do_visual_test)
19503 DWORD *ptr = NULL;
19504 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19506 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19508 width = tests[i].src_width;
19509 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19510 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19512 for (l = 0; l < tests[i].src_levels; ++l)
19514 switch (texture_types[t].type)
19516 case D3DRTYPE_TEXTURE:
19517 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19518 l, &locked_rect, NULL, 0);
19519 ptr = locked_rect.pBits;
19520 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19521 break;
19522 case D3DRTYPE_CUBETEXTURE:
19523 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19524 f, l, &locked_rect, NULL, 0);
19525 ptr = locked_rect.pBits;
19526 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19527 break;
19528 case D3DRTYPE_VOLUMETEXTURE:
19529 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19530 l, &locked_box, NULL, 0);
19531 ptr = locked_box.pBits;
19532 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19533 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19534 break;
19535 default:
19536 trace("Unexpected resource type.\n");
19538 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19540 for (z = 0; z < depth; ++z)
19542 for (y = 0; y < height; ++y)
19544 for (x = 0; x < width; ++x)
19546 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19547 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19548 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19553 switch (texture_types[t].type)
19555 case D3DRTYPE_TEXTURE:
19556 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19557 break;
19558 case D3DRTYPE_CUBETEXTURE:
19559 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19560 break;
19561 case D3DRTYPE_VOLUMETEXTURE:
19562 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19563 break;
19564 default:
19565 trace("Unexpected resource type.\n");
19567 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19569 width >>= 1;
19570 if (!width)
19571 width = 1;
19572 height >>= 1;
19573 if (!height)
19574 height = 1;
19575 depth >>= 1;
19576 if (!depth)
19577 depth = 1;
19582 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
19583 if (FAILED(hr))
19585 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19586 IDirect3DBaseTexture9_Release(src);
19587 IDirect3DBaseTexture9_Release(dst);
19588 continue;
19590 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19592 if (do_visual_test)
19594 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
19595 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
19598 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19600 hr = IDirect3DDevice9_BeginScene(device);
19601 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19603 texture_types[t].quad, texture_types[t].vertex_size);
19604 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19605 hr = IDirect3DDevice9_EndScene(device);
19606 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19608 color = getPixelColor(device, 320, 240);
19609 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
19610 || broken(color == 0xdeadbeec), /* WARP device often just breaks down. */
19611 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
19614 IDirect3DBaseTexture9_Release(src);
19615 IDirect3DBaseTexture9_Release(dst);
19618 refcount = IDirect3DDevice9_Release(device);
19619 ok(!refcount, "Device has %u references left.\n", refcount);
19620 IDirect3D9_Release(d3d9);
19621 DestroyWindow(window);
19624 START_TEST(visual)
19626 D3DADAPTER_IDENTIFIER9 identifier;
19627 IDirect3D9 *d3d;
19628 HRESULT hr;
19630 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
19632 skip("could not create D3D9 object\n");
19633 return;
19636 memset(&identifier, 0, sizeof(identifier));
19637 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
19638 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
19639 trace("Driver string: \"%s\"\n", identifier.Driver);
19640 trace("Description string: \"%s\"\n", identifier.Description);
19641 /* Only Windows XP's default VGA driver should have an empty description */
19642 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
19643 trace("Device name string: \"%s\"\n", identifier.DeviceName);
19644 ok(identifier.DeviceName[0], "Empty device name.\n");
19645 trace("Driver version %d.%d.%d.%d\n",
19646 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
19647 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
19649 IDirect3D9_Release(d3d);
19651 test_sanity();
19652 depth_clamp_test();
19653 stretchrect_test();
19654 lighting_test();
19655 test_specular_lighting();
19656 clear_test();
19657 color_fill_test();
19658 fog_test();
19659 test_cube_wrap();
19660 z_range_test();
19661 maxmip_test();
19662 offscreen_test();
19663 ds_size_test();
19664 test_blend();
19665 shademode_test();
19666 srgbtexture_test();
19667 release_buffer_test();
19668 float_texture_test();
19669 g16r16_texture_test();
19670 pixelshader_blending_test();
19671 texture_transform_flags_test();
19672 autogen_mipmap_test();
19673 fixed_function_decl_test();
19674 conditional_np2_repeat_test();
19675 fixed_function_bumpmap_test();
19676 pointsize_test();
19677 tssargtemp_test();
19678 np2_stretch_rect_test();
19679 yuv_color_test();
19680 yuv_layout_test();
19681 zwriteenable_test();
19682 alphatest_test();
19683 viewport_test();
19684 test_constant_clamp_vs();
19685 test_compare_instructions();
19686 test_mova();
19687 loop_index_test();
19688 sincos_test();
19689 sgn_test();
19690 clip_planes_test();
19691 test_vshader_input();
19692 test_vshader_float16();
19693 stream_test();
19694 fog_with_shader_test();
19695 texbem_test();
19696 texdepth_test();
19697 texkill_test();
19698 volume_v16u16_test();
19699 constant_clamp_ps_test();
19700 cnd_test();
19701 dp2add_ps_test();
19702 unbound_sampler_test();
19703 nested_loop_test();
19704 pretransformed_varying_test();
19705 vface_register_test();
19706 test_fragment_coords();
19707 multiple_rendertargets_test();
19708 texop_test();
19709 texop_range_test();
19710 alphareplicate_test();
19711 dp3_alpha_test();
19712 depth_buffer_test();
19713 depth_buffer2_test();
19714 depth_blit_test();
19715 intz_test();
19716 shadow_test();
19717 fp_special_test();
19718 depth_bounds_test();
19719 srgbwrite_format_test();
19720 update_surface_test();
19721 multisample_get_rtdata_test();
19722 zenable_test();
19723 fog_special_test();
19724 volume_srgb_test();
19725 volume_dxt5_test();
19726 add_dirty_rect_test();
19727 multisampled_depth_buffer_test();
19728 resz_test();
19729 stencil_cull_test();
19730 test_per_stage_constant();
19731 test_3dc_formats();
19732 test_fog_interpolation();
19733 test_negative_fixedfunction_fog();
19734 test_position_index();
19735 test_table_fog_zw();
19736 test_signed_formats();
19737 test_multisample_mismatch();
19738 test_texcoordindex();
19739 test_vertex_blending();
19740 test_updatetexture();