wined3d: Drop redundant check for instanced rendering from drawStridedFast.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blobfb0b1b5d2fba028b9c005abc1c43d5ac7808317b
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 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 struct vec2
37 float x, y;
40 struct vec3
42 float x, y, z;
45 struct vec4
47 float x, y, z, w;
50 static HWND create_window(void)
52 WNDCLASSA wc = {0};
53 HWND ret;
54 wc.lpfnWndProc = DefWindowProcA;
55 wc.lpszClassName = "d3d9_test_wc";
56 RegisterClassA(&wc);
58 ret = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_SYSMENU | WS_POPUP,
59 0, 0, 640, 480, 0, 0, 0, 0);
60 ShowWindow(ret, SW_SHOW);
61 return ret;
64 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
66 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
67 c1 >>= 8; c2 >>= 8;
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 return TRUE;
76 /* Locks a given surface and returns the color at (x,y). It's the caller's
77 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
78 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
80 DWORD color;
81 HRESULT hr;
82 D3DSURFACE_DESC desc;
83 RECT rectToLock = {x, y, x+1, y+1};
84 D3DLOCKED_RECT lockedRect;
86 hr = IDirect3DSurface9_GetDesc(surface, &desc);
87 if(FAILED(hr)) /* This is not a test */
89 trace("Can't get the surface description, hr=%08x\n", hr);
90 return 0xdeadbeef;
93 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
94 if(FAILED(hr)) /* This is not a test */
96 trace("Can't lock the surface, hr=%08x\n", hr);
97 return 0xdeadbeef;
99 switch(desc.Format) {
100 case D3DFMT_A8R8G8B8:
102 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
103 break;
105 default:
106 trace("Error: unknown surface format: %d\n", desc.Format);
107 color = 0xdeadbeef;
108 break;
110 hr = IDirect3DSurface9_UnlockRect(surface);
111 if(FAILED(hr))
113 trace("Can't unlock the surface, hr=%08x\n", hr);
115 return color;
118 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
120 DWORD ret;
121 IDirect3DSurface9 *surf = NULL, *target = NULL;
122 HRESULT hr;
123 D3DLOCKED_RECT lockedRect;
124 RECT rectToLock = {x, y, x+1, y+1};
126 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
127 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
128 if (FAILED(hr) || !surf)
130 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
131 return 0xdeadbeef;
134 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
135 if(FAILED(hr))
137 trace("Can't get the render target, hr=%08x\n", hr);
138 ret = 0xdeadbeed;
139 goto out;
142 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
143 if (FAILED(hr))
145 trace("Can't read the render target data, hr=%08x\n", hr);
146 ret = 0xdeadbeec;
147 goto out;
150 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
151 if(FAILED(hr))
153 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
154 ret = 0xdeadbeeb;
155 goto out;
158 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
159 * really important for these tests
161 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
162 hr = IDirect3DSurface9_UnlockRect(surf);
163 if(FAILED(hr))
165 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
168 out:
169 if(target) IDirect3DSurface9_Release(target);
170 if(surf) IDirect3DSurface9_Release(surf);
171 return ret;
174 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
176 D3DPRESENT_PARAMETERS present_parameters = {0};
177 IDirect3DDevice9 *device;
179 present_parameters.Windowed = windowed;
180 present_parameters.hDeviceWindow = device_window;
181 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
182 present_parameters.BackBufferWidth = 640;
183 present_parameters.BackBufferHeight = 480;
184 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
185 present_parameters.EnableAutoDepthStencil = TRUE;
186 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
188 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
189 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
190 return device;
192 return NULL;
195 static void cleanup_device(IDirect3DDevice9 *device)
197 if (device)
199 D3DPRESENT_PARAMETERS present_parameters;
200 IDirect3DSwapChain9 *swapchain;
201 ULONG ref;
203 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
204 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
205 IDirect3DSwapChain9_Release(swapchain);
206 ref = IDirect3DDevice9_Release(device);
207 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
208 DestroyWindow(present_parameters.hDeviceWindow);
212 static void test_sanity(void)
214 IDirect3DDevice9 *device;
215 IDirect3D9 *d3d;
216 D3DCOLOR color;
217 ULONG refcount;
218 HWND window;
219 HRESULT hr;
221 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
222 0, 0, 640, 480, NULL, NULL, NULL, NULL);
223 d3d = Direct3DCreate9(D3D_SDK_VERSION);
224 ok(!!d3d, "Failed to create a D3D object.\n");
225 if (!(device = create_device(d3d, window, window, TRUE)))
227 skip("Failed to create a D3D device, skipping tests.\n");
228 goto done;
231 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
232 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
233 color = getPixelColor(device, 1, 1);
234 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
237 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
240 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
241 color = getPixelColor(device, 639, 479);
242 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
244 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
245 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
247 refcount = IDirect3DDevice9_Release(device);
248 ok(!refcount, "Device has %u references left.\n", refcount);
249 done:
250 IDirect3D9_Release(d3d);
251 DestroyWindow(window);
254 static void lighting_test(void)
256 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
257 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
258 IDirect3DDevice9 *device;
259 D3DMATERIAL9 material;
260 IDirect3D9 *d3d;
261 D3DCOLOR color;
262 ULONG refcount;
263 HWND window;
264 HRESULT hr;
266 static const D3DMATRIX mat =
268 1.0f, 0.0f, 0.0f, 0.0f,
269 0.0f, 1.0f, 0.0f, 0.0f,
270 0.0f, 0.0f, 1.0f, 0.0f,
271 0.0f, 0.0f, 0.0f, 1.0f,
272 }}};
273 static const struct
275 struct vec3 position;
276 DWORD diffuse;
278 unlitquad[] =
280 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
281 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
282 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
283 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
285 litquad[] =
287 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
288 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
289 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
290 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
292 lighting_test[] =
294 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
295 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
296 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
297 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
299 static const struct
301 struct vec3 position;
302 struct vec3 normal;
303 DWORD diffuse;
305 unlitnquad[] =
307 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
308 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
309 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
310 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
312 litnquad[] =
314 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
315 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
316 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
317 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
319 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
321 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
322 0, 0, 640, 480, NULL, NULL, NULL, NULL);
323 d3d = Direct3DCreate9(D3D_SDK_VERSION);
324 ok(!!d3d, "Failed to create a D3D object.\n");
325 if (!(device = create_device(d3d, window, window, TRUE)))
327 skip("Failed to create a D3D device, skipping tests.\n");
328 goto done;
331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
332 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
334 /* Setup some states that may cause issues */
335 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
336 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
337 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
338 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
339 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
340 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
341 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
342 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
343 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
344 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
345 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
346 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
348 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
350 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
351 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
352 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
354 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
355 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
356 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
358 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
360 hr = IDirect3DDevice9_SetFVF(device, 0);
361 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
363 hr = IDirect3DDevice9_SetFVF(device, fvf);
364 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
366 hr = IDirect3DDevice9_BeginScene(device);
367 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
369 /* No lights are defined... That means, lit vertices should be entirely black */
370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
371 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
372 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
373 2 /* PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
374 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
377 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
378 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
379 2 /* PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
380 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
382 hr = IDirect3DDevice9_SetFVF(device, nfvf);
383 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
386 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
387 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
388 2 /* PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
389 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
392 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
393 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
394 2 /* PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
395 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
397 hr = IDirect3DDevice9_EndScene(device);
398 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
400 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
401 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
402 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
403 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
404 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
405 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
406 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
407 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
409 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
411 memset(&material, 0, sizeof(material));
412 material.Diffuse.r = 0.0;
413 material.Diffuse.g = 0.0;
414 material.Diffuse.b = 0.0;
415 material.Diffuse.a = 1.0;
416 material.Ambient.r = 0.0;
417 material.Ambient.g = 0.0;
418 material.Ambient.b = 0.0;
419 material.Ambient.a = 0.0;
420 material.Specular.r = 0.0;
421 material.Specular.g = 0.0;
422 material.Specular.b = 0.0;
423 material.Specular.a = 0.0;
424 material.Emissive.r = 0.0;
425 material.Emissive.g = 0.0;
426 material.Emissive.b = 0.0;
427 material.Emissive.a = 0.0;
428 material.Power = 0.0;
429 hr = IDirect3DDevice9_SetMaterial(device, &material);
430 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
435 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
437 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
438 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
439 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
440 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
442 hr = IDirect3DDevice9_BeginScene(device);
443 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
445 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
446 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
447 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
448 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
450 hr = IDirect3DDevice9_EndScene(device);
451 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
453 color = getPixelColor(device, 320, 240);
454 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
455 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
457 refcount = IDirect3DDevice9_Release(device);
458 ok(!refcount, "Device has %u references left.\n", refcount);
459 done:
460 IDirect3D9_Release(d3d);
461 DestroyWindow(window);
464 static void clear_test(void)
466 /* Tests the correctness of clearing parameters */
467 HRESULT hr;
468 D3DRECT rect[2];
469 D3DRECT rect_negneg;
470 DWORD color;
471 D3DVIEWPORT9 old_vp, vp;
472 RECT scissor;
473 DWORD oldColorWrite;
474 BOOL invalid_clear_failed = FALSE;
475 IDirect3DDevice9 *device;
476 IDirect3D9 *d3d;
477 ULONG refcount;
478 HWND window;
480 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
481 0, 0, 640, 480, NULL, NULL, NULL, NULL);
482 d3d = Direct3DCreate9(D3D_SDK_VERSION);
483 ok(!!d3d, "Failed to create a D3D object.\n");
484 if (!(device = create_device(d3d, window, window, TRUE)))
486 skip("Failed to create a D3D device, skipping tests.\n");
487 goto done;
490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
491 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
493 /* Positive x, negative y */
494 rect[0].x1 = 0;
495 rect[0].y1 = 480;
496 rect[0].x2 = 320;
497 rect[0].y2 = 240;
499 /* Positive x, positive y */
500 rect[1].x1 = 0;
501 rect[1].y1 = 0;
502 rect[1].x2 = 320;
503 rect[1].y2 = 240;
504 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
505 * returns D3D_OK, but ignores the rectangle silently
507 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
508 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
511 /* negative x, negative y */
512 rect_negneg.x1 = 640;
513 rect_negneg.y1 = 240;
514 rect_negneg.x2 = 320;
515 rect_negneg.y2 = 0;
516 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
517 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
518 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
520 color = getPixelColor(device, 160, 360); /* lower left quad */
521 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
522 color = getPixelColor(device, 160, 120); /* upper left quad */
523 if(invalid_clear_failed) {
524 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
525 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
526 } else {
527 /* If the negative rectangle was dropped silently, the correct ones are cleared */
528 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
530 color = getPixelColor(device, 480, 360); /* lower right quad */
531 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
532 color = getPixelColor(device, 480, 120); /* upper right quad */
533 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
535 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
537 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
538 * clear the red quad in the top left part of the render target. For some reason it
539 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
540 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
541 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
542 * pick some obvious value
544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
545 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
547 /* Test how the viewport affects clears */
548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
549 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
550 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
551 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
553 vp.X = 160;
554 vp.Y = 120;
555 vp.Width = 160;
556 vp.Height = 120;
557 vp.MinZ = 0.0;
558 vp.MaxZ = 1.0;
559 hr = IDirect3DDevice9_SetViewport(device, &vp);
560 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
561 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
562 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
564 vp.X = 320;
565 vp.Y = 240;
566 vp.Width = 320;
567 vp.Height = 240;
568 vp.MinZ = 0.0;
569 vp.MaxZ = 1.0;
570 hr = IDirect3DDevice9_SetViewport(device, &vp);
571 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
572 rect[0].x1 = 160;
573 rect[0].y1 = 120;
574 rect[0].x2 = 480;
575 rect[0].y2 = 360;
576 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
577 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
579 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
580 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
582 color = getPixelColor(device, 158, 118);
583 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
584 color = getPixelColor(device, 162, 118);
585 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
586 color = getPixelColor(device, 158, 122);
587 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
588 color = getPixelColor(device, 162, 122);
589 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
591 color = getPixelColor(device, 318, 238);
592 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
593 color = getPixelColor(device, 322, 238);
594 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
595 color = getPixelColor(device, 318, 242);
596 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
597 color = getPixelColor(device, 322, 242);
598 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
600 color = getPixelColor(device, 478, 358);
601 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
602 color = getPixelColor(device, 482, 358);
603 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
604 color = getPixelColor(device, 478, 362);
605 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
606 color = getPixelColor(device, 482, 362);
607 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
609 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
611 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
612 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
614 scissor.left = 160;
615 scissor.right = 480;
616 scissor.top = 120;
617 scissor.bottom = 360;
618 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
619 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
621 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
623 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
624 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
625 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
626 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
629 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
631 color = getPixelColor(device, 158, 118);
632 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
633 color = getPixelColor(device, 162, 118);
634 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
635 color = getPixelColor(device, 158, 122);
636 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
637 color = getPixelColor(device, 162, 122);
638 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
640 color = getPixelColor(device, 158, 358);
641 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
642 color = getPixelColor(device, 162, 358);
643 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
644 color = getPixelColor(device, 158, 358);
645 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
646 color = getPixelColor(device, 162, 362);
647 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
649 color = getPixelColor(device, 478, 118);
650 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
651 color = getPixelColor(device, 478, 122);
652 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
653 color = getPixelColor(device, 482, 122);
654 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
655 color = getPixelColor(device, 482, 358);
656 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
658 color = getPixelColor(device, 478, 358);
659 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
660 color = getPixelColor(device, 478, 362);
661 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
662 color = getPixelColor(device, 482, 358);
663 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
664 color = getPixelColor(device, 482, 362);
665 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
667 color = getPixelColor(device, 318, 238);
668 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
669 color = getPixelColor(device, 318, 242);
670 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
671 color = getPixelColor(device, 322, 238);
672 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
673 color = getPixelColor(device, 322, 242);
674 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
676 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
678 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
679 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
683 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
685 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
687 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
688 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
693 /* Colorwriteenable does not affect the clear */
694 color = getPixelColor(device, 320, 240);
695 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
697 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
699 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
700 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
702 rect[0].x1 = 0;
703 rect[0].y1 = 0;
704 rect[0].x2 = 640;
705 rect[0].y2 = 480;
706 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
707 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
709 color = getPixelColor(device, 320, 240);
710 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
711 "Clear with count = 0, rect != NULL has color %08x\n", color);
713 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
715 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
716 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
717 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
718 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
720 color = getPixelColor(device, 320, 240);
721 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
722 "Clear with count = 1, rect = NULL has color %08x\n", color);
724 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
726 refcount = IDirect3DDevice9_Release(device);
727 ok(!refcount, "Device has %u references left.\n", refcount);
728 done:
729 IDirect3D9_Release(d3d);
730 DestroyWindow(window);
733 static void color_fill_test(void)
735 IDirect3DSurface9 *offscreen_surface;
736 IDirect3DSurface9 *backbuffer;
737 IDirect3DSurface9 *rt_surface;
738 D3DCOLOR fill_color, color;
739 IDirect3DDevice9 *device;
740 IDirect3D9 *d3d;
741 ULONG refcount;
742 HWND window;
743 HRESULT hr;
745 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
746 0, 0, 640, 480, NULL, NULL, NULL, NULL);
747 d3d = Direct3DCreate9(D3D_SDK_VERSION);
748 ok(!!d3d, "Failed to create a D3D object.\n");
749 if (!(device = create_device(d3d, window, window, TRUE)))
751 skip("Failed to create a D3D device, skipping tests.\n");
752 goto done;
755 /* Test ColorFill on a the backbuffer (should pass) */
756 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
757 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
759 fill_color = 0x112233;
760 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
761 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
763 color = getPixelColor(device, 0, 0);
764 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
766 IDirect3DSurface9_Release(backbuffer);
768 /* Test ColorFill on a render target surface (should pass) */
769 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
770 D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
771 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
773 fill_color = 0x445566;
774 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
775 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
777 color = getPixelColorFromSurface(rt_surface, 0, 0);
778 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
780 IDirect3DSurface9_Release(rt_surface);
782 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
783 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
784 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
785 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
787 fill_color = 0x778899;
788 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
789 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
791 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
792 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
794 IDirect3DSurface9_Release(offscreen_surface);
796 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
797 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
798 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
799 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
801 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
802 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
804 IDirect3DSurface9_Release(offscreen_surface);
806 refcount = IDirect3DDevice9_Release(device);
807 ok(!refcount, "Device has %u references left.\n", refcount);
808 done:
809 IDirect3D9_Release(d3d);
810 DestroyWindow(window);
814 * c7 mova ARGB mov ARGB
815 * -2.4 -2 0x00ffff00 -3 0x00ff0000
816 * -1.6 -2 0x00ffff00 -2 0x00ffff00
817 * -0.4 0 0x0000ffff -1 0x0000ff00
818 * 0.4 0 0x0000ffff 0 0x0000ffff
819 * 1.6 2 0x00ff00ff 1 0x000000ff
820 * 2.4 2 0x00ff00ff 2 0x00ff00ff
822 static void test_mova(void)
824 IDirect3DVertexDeclaration9 *vertex_declaration;
825 IDirect3DVertexShader9 *mova_shader;
826 IDirect3DVertexShader9 *mov_shader;
827 IDirect3DDevice9 *device;
828 unsigned int i, j;
829 IDirect3D9 *d3d;
830 ULONG refcount;
831 D3DCAPS9 caps;
832 HWND window;
833 HRESULT hr;
835 static const DWORD mova_test[] =
837 0xfffe0200, /* vs_2_0 */
838 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
839 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
840 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
841 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
842 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
843 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
844 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
845 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
846 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
847 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
848 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
849 0x0000ffff /* END */
851 static const DWORD mov_test[] =
853 0xfffe0101, /* vs_1_1 */
854 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
855 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
856 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
857 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
858 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
859 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
860 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
861 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
862 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
863 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
864 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
865 0x0000ffff /* END */
867 static const struct
869 float in[4];
870 DWORD out;
872 test_data[2][6] =
875 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
876 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
877 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
878 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
879 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
880 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
883 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
884 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
885 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
886 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
887 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
888 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
891 static const struct vec3 quad[] =
893 {-1.0f, -1.0f, 0.0f},
894 {-1.0f, 1.0f, 0.0f},
895 { 1.0f, -1.0f, 0.0f},
896 { 1.0f, 1.0f, 0.0f},
898 static const D3DVERTEXELEMENT9 decl_elements[] =
900 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
901 D3DDECL_END()
904 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
905 0, 0, 640, 480, NULL, NULL, NULL, NULL);
906 d3d = Direct3DCreate9(D3D_SDK_VERSION);
907 ok(!!d3d, "Failed to create a D3D object.\n");
908 if (!(device = create_device(d3d, window, window, TRUE)))
910 skip("Failed to create a D3D device, skipping tests.\n");
911 goto done;
914 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
916 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
918 skip("No vs_2_0 support, skipping tests.\n");
919 IDirect3DDevice9_Release(device);
920 goto done;
923 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
924 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
925 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
926 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
927 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
928 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
929 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
930 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
932 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
933 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
934 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
936 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
938 DWORD color;
940 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
941 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
943 hr = IDirect3DDevice9_BeginScene(device);
944 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
947 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
949 hr = IDirect3DDevice9_EndScene(device);
950 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
952 color = getPixelColor(device, 320, 240);
953 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
954 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
956 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
957 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
959 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
960 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
962 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
963 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
966 IDirect3DVertexDeclaration9_Release(vertex_declaration);
967 IDirect3DVertexShader9_Release(mova_shader);
968 IDirect3DVertexShader9_Release(mov_shader);
969 refcount = IDirect3DDevice9_Release(device);
970 ok(!refcount, "Device has %u references left.\n", refcount);
971 done:
972 IDirect3D9_Release(d3d);
973 DestroyWindow(window);
976 static void fog_test(void)
978 float start = 0.0f, end = 1.0f;
979 IDirect3DDevice9 *device;
980 IDirect3D9 *d3d;
981 D3DCOLOR color;
982 ULONG refcount;
983 D3DCAPS9 caps;
984 HWND window;
985 HRESULT hr;
986 int i;
988 /* Gets full z based fog with linear fog, no fog with specular color. */
989 static const struct
991 float x, y, z;
992 D3DCOLOR diffuse;
993 D3DCOLOR specular;
995 untransformed_1[] =
997 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
998 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
999 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1000 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1002 /* Ok, I am too lazy to deal with transform matrices. */
1003 untransformed_2[] =
1005 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1006 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1007 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1008 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1010 untransformed_3[] =
1012 {-1.0f, -1.0f, 0.4999f, 0xffff0000, 0xff000000},
1013 {-1.0f, 1.0f, 0.4999f, 0xffff0000, 0xff000000},
1014 { 1.0f, -1.0f, 0.4999f, 0xffff0000, 0xff000000},
1015 { 1.0f, 1.0f, 0.4999f, 0xffff0000, 0xff000000},
1017 far_quad1[] =
1019 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1020 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1021 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1022 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1024 far_quad2[] =
1026 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1027 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1028 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1029 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1031 /* Untransformed ones. Give them a different diffuse color to make the
1032 * test look nicer. It also makes making sure that they are drawn
1033 * correctly easier. */
1034 static const struct
1036 float x, y, z, rhw;
1037 D3DCOLOR diffuse;
1038 D3DCOLOR specular;
1040 transformed_1[] =
1042 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1043 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1044 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1045 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1047 transformed_2[] =
1049 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1050 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1051 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1052 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1054 static const struct
1056 struct vec3 position;
1057 DWORD diffuse;
1059 rev_fog_quads[] =
1061 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1062 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1063 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1064 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1066 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1067 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1068 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1069 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1071 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1072 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1073 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1074 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1076 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1077 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1078 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1079 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1081 static const D3DMATRIX ident_mat =
1083 1.0f, 0.0f, 0.0f, 0.0f,
1084 0.0f, 1.0f, 0.0f, 0.0f,
1085 0.0f, 0.0f, 1.0f, 0.0f,
1086 0.0f, 0.0f, 0.0f, 1.0f
1087 }}};
1088 static const D3DMATRIX world_mat1 =
1090 1.0f, 0.0f, 0.0f, 0.0f,
1091 0.0f, 1.0f, 0.0f, 0.0f,
1092 0.0f, 0.0f, 1.0f, 0.0f,
1093 0.0f, 0.0f, -0.5f, 1.0f
1094 }}};
1095 static const D3DMATRIX world_mat2 =
1097 1.0f, 0.0f, 0.0f, 0.0f,
1098 0.0f, 1.0f, 0.0f, 0.0f,
1099 0.0f, 0.0f, 1.0f, 0.0f,
1100 0.0f, 0.0f, 1.0f, 1.0f
1101 }}};
1102 static const D3DMATRIX proj_mat =
1104 1.0f, 0.0f, 0.0f, 0.0f,
1105 0.0f, 1.0f, 0.0f, 0.0f,
1106 0.0f, 0.0f, 1.0f, 0.0f,
1107 0.0f, 0.0f, -1.0f, 1.0f
1108 }}};
1109 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1110 static const WORD Indices2[] =
1112 0, 1, 2, 2, 3, 0,
1113 4, 5, 6, 6, 7, 4,
1114 8, 9, 10, 10, 11, 8,
1115 12, 13, 14, 14, 15, 12,
1118 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1119 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1120 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1121 ok(!!d3d, "Failed to create a D3D object.\n");
1122 if (!(device = create_device(d3d, window, window, TRUE)))
1124 skip("Failed to create a D3D device, skipping tests.\n");
1125 goto done;
1128 memset(&caps, 0, sizeof(caps));
1129 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1130 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1132 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1134 /* Setup initial states: No lighting, fog on, fog color */
1135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1136 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1138 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1140 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1142 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1143 /* Some of the tests seem to depend on the projection matrix explicitly
1144 * being set to an identity matrix, even though that's the default.
1145 * (AMD Radeon HD 6310, Windows 7) */
1146 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1147 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1149 /* First test: Both table fog and vertex fog off */
1150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1151 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1153 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1155 /* Start = 0, end = 1. Should be default, but set them */
1156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1157 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1159 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1161 hr = IDirect3DDevice9_BeginScene(device);
1162 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1164 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1165 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1167 /* Untransformed, vertex fog = NONE, table fog = NONE:
1168 * Read the fog weighting from the specular color. */
1169 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1170 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1171 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1173 /* That makes it use the Z value */
1174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1175 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1176 /* Untransformed, vertex fog != none (or table fog != none):
1177 * Use the Z value as input into the equation. */
1178 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1179 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1182 /* transformed verts */
1183 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1184 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1185 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1186 * Use specular color alpha component. */
1187 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1188 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1189 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1192 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1193 /* Transformed, table fog != none, vertex anything:
1194 * Use Z value as input to the fog equation. */
1195 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1196 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1197 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1199 hr = IDirect3DDevice9_EndScene(device);
1200 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1202 color = getPixelColor(device, 160, 360);
1203 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1204 color = getPixelColor(device, 160, 120);
1205 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1206 color = getPixelColor(device, 480, 120);
1207 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1208 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1210 color = getPixelColor(device, 480, 360);
1211 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1213 else
1215 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1216 * The settings above result in no fogging with vertex fog
1218 color = getPixelColor(device, 480, 120);
1219 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1220 trace("Info: Table fog not supported by this device\n");
1222 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1224 /* Now test the special case fogstart == fogend */
1225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1226 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1228 hr = IDirect3DDevice9_BeginScene(device);
1229 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1231 start = 512;
1232 end = 512;
1233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1234 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1235 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1236 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1238 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1239 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1241 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1243 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1245 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1246 * Would result in a completely fog-free primitive because start > zcoord,
1247 * but because start == end, the primitive is fully covered by fog. The
1248 * same happens to the 2nd untransformed quad with z = 1.0. The third
1249 * transformed quad remains unfogged because the fogcoords are read from
1250 * the specular color and has fixed fogstart and fogend. */
1251 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1252 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1253 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1254 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1255 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1256 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1258 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1259 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1260 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1261 * Use specular color alpha component. */
1262 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1263 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1264 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1266 hr = IDirect3DDevice9_EndScene(device);
1267 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1269 color = getPixelColor(device, 160, 360);
1270 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1271 color = getPixelColor(device, 160, 120);
1272 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1273 color = getPixelColor(device, 480, 120);
1274 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1275 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1277 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1278 * but without shaders it seems to work everywhere
1280 end = 0.2;
1281 start = 0.8;
1282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1283 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1285 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1286 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1287 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1289 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1290 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1291 * so skip this for now
1293 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1294 const char *mode = (i ? "table" : "vertex");
1295 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1296 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1298 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1300 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1301 hr = IDirect3DDevice9_BeginScene(device);
1302 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1303 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1304 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1305 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1306 hr = IDirect3DDevice9_EndScene(device);
1307 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1309 color = getPixelColor(device, 160, 360);
1310 ok(color_match(color, 0x0000ff00, 1),
1311 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1313 color = getPixelColor(device, 160, 120);
1314 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1315 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1317 color = getPixelColor(device, 480, 120);
1318 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1319 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1321 color = getPixelColor(device, 480, 360);
1322 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1324 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1326 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1327 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1328 break;
1332 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1334 /* A simple fog + non-identity world matrix test */
1335 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1336 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1338 start = 0.0;
1339 end = 1.0;
1340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1341 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1343 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1345 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1347 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1349 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1350 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1352 hr = IDirect3DDevice9_BeginScene(device);
1353 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1355 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1356 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1358 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1359 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1360 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1361 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1362 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1363 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1365 hr = IDirect3DDevice9_EndScene(device);
1366 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1368 color = getPixelColor(device, 160, 360);
1369 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1370 "Unfogged quad has color %08x\n", color);
1371 color = getPixelColor(device, 160, 120);
1372 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1373 "Fogged out quad has color %08x\n", color);
1375 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1377 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1378 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1379 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1380 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1381 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1384 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1386 hr = IDirect3DDevice9_BeginScene(device);
1387 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1390 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1392 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1393 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1394 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1395 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1396 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1397 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1399 hr = IDirect3DDevice9_EndScene(device);
1400 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1402 color = getPixelColor(device, 160, 360);
1403 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1404 color = getPixelColor(device, 160, 120);
1405 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1406 "Fogged out quad has color %08x\n", color);
1408 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1410 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
1411 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1412 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1413 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1415 else
1417 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1420 /* Test RANGEFOG vs FOGTABLEMODE */
1421 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1422 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1425 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1426 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1429 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1430 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1432 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1433 * is not used, the fog coordinate will be equal to fogstart and the quad not
1434 * fogged. If range fog is used the fog coordinate will be slightly higher and
1435 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1436 * is calculated per vertex and interpolated, so even the center of the screen
1437 * where the difference doesn't matter will be fogged, but check the corners in
1438 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1439 start = 0.5f;
1440 end = 0.50001f;
1441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1442 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1444 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1446 /* Table fog: Range fog is not used */
1447 hr = IDirect3DDevice9_BeginScene(device);
1448 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1451 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
1453 untransformed_3, sizeof(*untransformed_3));
1454 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1456 hr = IDirect3DDevice9_EndScene(device);
1457 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1459 color = getPixelColor(device, 10, 10);
1460 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1461 color = getPixelColor(device, 630, 10);
1462 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1463 color = getPixelColor(device, 10, 470);
1464 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1465 color = getPixelColor(device, 630, 470);
1466 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1469 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1471 /* Vertex fog: Rangefog is used */
1472 hr = IDirect3DDevice9_BeginScene(device);
1473 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1476 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1478 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
1480 untransformed_3, sizeof(*untransformed_3));
1481 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1483 hr = IDirect3DDevice9_EndScene(device);
1484 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1486 color = getPixelColor(device, 10, 10);
1487 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1488 "Rangefog with vertex fog returned color 0x%08x\n", color);
1489 color = getPixelColor(device, 630, 10);
1490 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1491 "Rangefog with vertex fog returned color 0x%08x\n", color);
1492 color = getPixelColor(device, 10, 470);
1493 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1494 "Rangefog with vertex fog returned color 0x%08x\n", color);
1495 color = getPixelColor(device, 630, 470);
1496 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1497 "Rangefog with vertex fog returned color 0x%08x\n", color);
1499 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1500 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1503 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1505 else
1507 skip("Range fog or table fog not supported, skipping range fog tests\n");
1510 refcount = IDirect3DDevice9_Release(device);
1511 ok(!refcount, "Device has %u references left.\n", refcount);
1512 done:
1513 IDirect3D9_Release(d3d);
1514 DestroyWindow(window);
1517 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1518 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1519 * regardless of the actual addressing mode set. The way this test works is
1520 * that we sample in one of the corners of the cubemap with filtering enabled,
1521 * and check the interpolated color. There are essentially two reasonable
1522 * things an implementation can do: Either pick one of the faces and
1523 * interpolate the edge texel with itself (i.e., clamp within the face), or
1524 * interpolate between the edge texels of the three involved faces. It should
1525 * never involve the border color or the other side (texcoord wrapping) of a
1526 * face in the interpolation. */
1527 static void test_cube_wrap(void)
1529 IDirect3DVertexDeclaration9 *vertex_declaration;
1530 IDirect3DSurface9 *face_surface, *surface;
1531 IDirect3DCubeTexture9 *texture;
1532 D3DLOCKED_RECT locked_rect;
1533 IDirect3DDevice9 *device;
1534 unsigned int x, y, face;
1535 IDirect3D9 *d3d;
1536 ULONG refcount;
1537 D3DCAPS9 caps;
1538 HWND window;
1539 HRESULT hr;
1541 static const float quad[][6] =
1543 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1544 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1545 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1546 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1548 static const D3DVERTEXELEMENT9 decl_elements[] =
1550 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1551 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1552 D3DDECL_END()
1554 static const struct
1556 D3DTEXTUREADDRESS mode;
1557 const char *name;
1559 address_modes[] =
1561 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1562 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1563 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1564 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1565 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1568 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1569 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1570 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1571 ok(!!d3d, "Failed to create a D3D object.\n");
1572 if (!(device = create_device(d3d, window, window, TRUE)))
1574 skip("Failed to create a D3D device, skipping tests.\n");
1575 goto done;
1578 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1579 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1580 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1582 skip("No cube texture support, skipping tests.\n");
1583 IDirect3DDevice9_Release(device);
1584 goto done;
1587 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1588 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1589 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1590 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1592 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1593 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1594 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1596 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1597 D3DPOOL_DEFAULT, &texture, NULL);
1598 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1600 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1601 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1603 for (y = 0; y < 128; ++y)
1605 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1606 for (x = 0; x < 64; ++x)
1608 *ptr++ = 0xff0000ff;
1610 for (x = 64; x < 128; ++x)
1612 *ptr++ = 0xffff0000;
1616 hr = IDirect3DSurface9_UnlockRect(surface);
1617 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1619 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1620 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1622 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1623 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1625 IDirect3DSurface9_Release(face_surface);
1627 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1628 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1630 for (y = 0; y < 128; ++y)
1632 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1633 for (x = 0; x < 64; ++x)
1635 *ptr++ = 0xffff0000;
1637 for (x = 64; x < 128; ++x)
1639 *ptr++ = 0xff0000ff;
1643 hr = IDirect3DSurface9_UnlockRect(surface);
1644 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1646 /* Create cube faces */
1647 for (face = 1; face < 6; ++face)
1649 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1650 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1652 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1653 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1655 IDirect3DSurface9_Release(face_surface);
1658 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1659 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1661 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1662 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1663 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1664 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1665 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1666 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1668 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1669 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1671 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1673 DWORD color;
1675 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1676 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1677 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1678 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1680 hr = IDirect3DDevice9_BeginScene(device);
1681 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1684 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1686 hr = IDirect3DDevice9_EndScene(device);
1687 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1689 color = getPixelColor(device, 320, 240);
1690 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1691 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1692 color, address_modes[x].name);
1694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1695 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1697 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1698 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1701 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1702 IDirect3DCubeTexture9_Release(texture);
1703 IDirect3DSurface9_Release(surface);
1704 refcount = IDirect3DDevice9_Release(device);
1705 ok(!refcount, "Device has %u references left.\n", refcount);
1706 done:
1707 IDirect3D9_Release(d3d);
1708 DestroyWindow(window);
1711 static void offscreen_test(void)
1713 IDirect3DSurface9 *backbuffer, *offscreen;
1714 IDirect3DTexture9 *offscreenTexture;
1715 IDirect3DDevice9 *device;
1716 IDirect3D9 *d3d;
1717 D3DCOLOR color;
1718 ULONG refcount;
1719 HWND window;
1720 HRESULT hr;
1722 static const float quad[][5] =
1724 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1725 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1726 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1727 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1730 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1731 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1732 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1733 ok(!!d3d, "Failed to create a D3D object.\n");
1734 if (!(device = create_device(d3d, window, window, TRUE)))
1736 skip("Failed to create a D3D device, skipping tests.\n");
1737 goto done;
1740 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
1741 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1743 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1744 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1745 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1746 if (!offscreenTexture)
1748 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
1749 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1750 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1751 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1752 if (!offscreenTexture)
1754 skip("Cannot create an offscreen render target.\n");
1755 IDirect3DDevice9_Release(device);
1756 goto done;
1760 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1761 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1763 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1764 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1766 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1767 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1769 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1770 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1771 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1772 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1773 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1774 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1775 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1776 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1778 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1780 hr = IDirect3DDevice9_BeginScene(device);
1781 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1783 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1784 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1785 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
1786 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1788 /* Draw without textures - Should result in a white quad. */
1789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1790 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1792 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1793 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1794 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
1795 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
1797 /* This time with the texture. */
1798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1799 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1801 hr = IDirect3DDevice9_EndScene(device);
1802 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1804 /* Center quad - should be white */
1805 color = getPixelColor(device, 320, 240);
1806 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1807 /* Some quad in the cleared part of the texture */
1808 color = getPixelColor(device, 170, 240);
1809 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1810 /* Part of the originally cleared back buffer */
1811 color = getPixelColor(device, 10, 10);
1812 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1813 color = getPixelColor(device, 10, 470);
1814 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1816 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1818 IDirect3DSurface9_Release(backbuffer);
1819 IDirect3DTexture9_Release(offscreenTexture);
1820 IDirect3DSurface9_Release(offscreen);
1821 refcount = IDirect3DDevice9_Release(device);
1822 ok(!refcount, "Device has %u references left.\n", refcount);
1823 done:
1824 IDirect3D9_Release(d3d);
1825 DestroyWindow(window);
1828 /* This test tests fog in combination with shaders.
1829 * What's tested: linear fog (vertex and table) with pixel shader
1830 * linear table fog with non foggy vertex shader
1831 * vertex fog with foggy vertex shader, non-linear
1832 * fog with shader, non-linear fog with foggy shader,
1833 * linear table fog with foggy shader */
1834 static void fog_with_shader_test(void)
1836 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
1837 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
1838 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1839 IDirect3DDevice9 *device;
1840 unsigned int i, j;
1841 IDirect3D9 *d3d;
1842 ULONG refcount;
1843 D3DCAPS9 caps;
1844 DWORD color;
1845 HWND window;
1846 HRESULT hr;
1847 union
1849 float f;
1850 DWORD i;
1851 } start, end;
1853 /* basic vertex shader without fog computation ("non foggy") */
1854 static const DWORD vertex_shader_code1[] =
1856 0xfffe0101, /* vs_1_1 */
1857 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1858 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1859 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1860 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1861 0x0000ffff
1863 /* basic vertex shader with reversed fog computation ("foggy") */
1864 static const DWORD vertex_shader_code2[] =
1866 0xfffe0101, /* vs_1_1 */
1867 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1868 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1869 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1870 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1871 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1872 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1873 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1874 0x0000ffff
1876 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1877 static const DWORD vertex_shader_code3[] =
1879 0xfffe0200, /* vs_2_0 */
1880 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1881 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1882 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1883 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1884 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1885 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1886 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1887 0x0000ffff
1889 /* basic pixel shader */
1890 static const DWORD pixel_shader_code[] =
1892 0xffff0101, /* ps_1_1 */
1893 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1894 0x0000ffff
1896 static const DWORD pixel_shader_code2[] =
1898 0xffff0200, /* ps_2_0 */
1899 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
1900 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
1901 0x0000ffff
1903 struct
1905 struct vec3 position;
1906 DWORD diffuse;
1908 quad[] =
1910 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1911 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1912 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1913 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1915 static const D3DVERTEXELEMENT9 decl_elements[] =
1917 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1918 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1919 D3DDECL_END()
1921 /* This reference data was collected on a nVidia GeForce 7600GS driver
1922 * version 84.19 DirectX version 9.0c on Windows XP. */
1923 static const struct test_data_t
1925 int vshader;
1926 int pshader;
1927 D3DFOGMODE vfog;
1928 D3DFOGMODE tfog;
1929 unsigned int color[11];
1931 test_data[] =
1933 /* only pixel shader: */
1934 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1935 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1936 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1937 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1938 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1939 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1940 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1941 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1942 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1943 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1944 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1945 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1946 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1947 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1948 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1950 /* vertex shader */
1951 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1952 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1953 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1954 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1955 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1956 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1957 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1958 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1959 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1961 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1962 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1963 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1964 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1965 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1966 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1968 /* vertex shader and pixel shader */
1969 /* The next 4 tests would read the fog coord output, but it isn't available.
1970 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1971 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1972 * These tests should be disabled if some other hardware behaves differently
1974 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1975 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1976 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1977 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1978 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1979 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1980 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1981 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1982 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1983 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1984 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1985 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1987 /* These use the Z coordinate with linear table fog */
1988 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1989 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1990 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1991 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1992 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1993 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1994 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1995 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1996 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1997 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1998 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1999 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2001 /* Non-linear table fog without fog coord */
2002 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2003 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2004 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2005 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2006 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2007 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2009 /* These tests fail on older Nvidia drivers */
2010 /* foggy vertex shader */
2011 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2012 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2013 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2014 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2015 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2016 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2017 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2018 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2019 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2020 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2021 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2022 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2024 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2025 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2026 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2027 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2028 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2029 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2030 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2031 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2032 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2033 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2034 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2035 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2037 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2038 * all using the fixed fog-coord linear fog
2040 /* vs_1_1 with ps_1_1 */
2041 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2042 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2043 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2044 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2045 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2046 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2047 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2048 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2049 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2050 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2051 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2052 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2054 /* vs_2_0 with ps_1_1 */
2055 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2056 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2057 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2058 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2059 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2060 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2061 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2062 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2063 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2064 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2065 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2066 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2068 /* vs_1_1 with ps_2_0 */
2069 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2070 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2071 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2072 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2073 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2074 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2075 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2076 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2077 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2078 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2079 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2080 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2082 /* vs_2_0 with ps_2_0 */
2083 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2084 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2085 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2086 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2087 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2088 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2089 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2090 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2091 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2092 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2093 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2094 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2096 /* These use table fog. Here the shader-provided fog coordinate is
2097 * ignored and the z coordinate used instead
2099 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2100 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2101 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2102 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2103 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2104 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2105 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2106 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2107 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2109 static const D3DMATRIX identity =
2111 1.0f, 0.0f, 0.0f, 0.0f,
2112 0.0f, 1.0f, 0.0f, 0.0f,
2113 0.0f, 0.0f, 1.0f, 0.0f,
2114 0.0f, 0.0f, 0.0f, 1.0f,
2115 }}};
2117 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2118 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2119 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2120 ok(!!d3d, "Failed to create a D3D object.\n");
2121 if (!(device = create_device(d3d, window, window, TRUE)))
2123 skip("Failed to create a D3D device, skipping tests.\n");
2124 goto done;
2127 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2128 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2129 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2131 skip("No shader model 2 support, skipping tests.\n");
2132 IDirect3DDevice9_Release(device);
2133 goto done;
2136 /* NOTE: Changing these values will not affect the tests with foggy vertex
2137 * shader, as the values are hardcoded in the shader. */
2138 start.f = 0.1f;
2139 end.f = 0.9f;
2141 /* Some of the tests seem to depend on the projection matrix explicitly
2142 * being set to an identity matrix, even though that's the default.
2143 * (AMD Radeon HD 6310, Windows 7) */
2144 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2145 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2147 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2148 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2149 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2150 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2151 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2152 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2153 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2154 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2155 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2156 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2157 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2158 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2160 /* Setup initial states: No lighting, fog on, fog color */
2161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2162 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2164 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2166 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2167 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2168 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2171 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2173 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2175 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2177 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2179 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2181 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2183 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2184 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2185 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2186 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2187 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2188 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2190 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2192 for(j=0; j < 11; j++)
2194 /* Don't use the whole zrange to prevent rounding errors */
2195 quad[0].position.z = 0.001f + (float)j / 10.02f;
2196 quad[1].position.z = 0.001f + (float)j / 10.02f;
2197 quad[2].position.z = 0.001f + (float)j / 10.02f;
2198 quad[3].position.z = 0.001f + (float)j / 10.02f;
2200 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2201 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2203 hr = IDirect3DDevice9_BeginScene(device);
2204 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2206 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2207 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2209 hr = IDirect3DDevice9_EndScene(device);
2210 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2212 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2213 color = getPixelColor(device, 128, 240);
2214 ok(color_match(color, test_data[i].color[j], 13),
2215 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2216 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2219 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2221 IDirect3DVertexShader9_Release(vertex_shader[1]);
2222 IDirect3DVertexShader9_Release(vertex_shader[2]);
2223 IDirect3DVertexShader9_Release(vertex_shader[3]);
2224 IDirect3DPixelShader9_Release(pixel_shader[1]);
2225 IDirect3DPixelShader9_Release(pixel_shader[2]);
2226 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2227 refcount = IDirect3DDevice9_Release(device);
2228 ok(!refcount, "Device has %u references left.\n", refcount);
2229 done:
2230 IDirect3D9_Release(d3d);
2231 DestroyWindow(window);
2234 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2235 unsigned int i, x, y;
2236 HRESULT hr;
2237 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2238 D3DLOCKED_RECT locked_rect;
2240 /* Generate the textures */
2241 for(i=0; i<2; i++)
2243 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2244 D3DPOOL_MANAGED, &texture[i], NULL);
2245 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2247 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2248 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2249 for (y = 0; y < 128; ++y)
2251 if(i)
2252 { /* Set up black texture with 2x2 texel white spot in the middle */
2253 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2254 for (x = 0; x < 128; ++x)
2256 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2259 else
2260 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2261 * (if multiplied with bumpenvmat)
2263 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2264 for (x = 0; x < 128; ++x)
2266 if(abs(x-64)>abs(y-64))
2268 if(x < 64)
2269 *ptr++ = 0xc000;
2270 else
2271 *ptr++ = 0x4000;
2273 else
2275 if(y < 64)
2276 *ptr++ = 0x0040;
2277 else
2278 *ptr++ = 0x00c0;
2283 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2284 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2286 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2287 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2289 /* Disable texture filtering */
2290 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2291 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2292 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2293 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2295 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2296 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2297 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2298 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2302 /* Test the behavior of the texbem instruction with normal 2D and projective
2303 * 2D textures. */
2304 static void texbem_test(void)
2306 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2307 /* Use asymmetric matrix to test loading. */
2308 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2309 IDirect3DPixelShader9 *pixel_shader = NULL;
2310 IDirect3DTexture9 *texture1, *texture2;
2311 IDirect3DTexture9 *texture = NULL;
2312 D3DLOCKED_RECT locked_rect;
2313 IDirect3DDevice9 *device;
2314 IDirect3D9 *d3d;
2315 ULONG refcount;
2316 D3DCAPS9 caps;
2317 DWORD color;
2318 HWND window;
2319 HRESULT hr;
2320 int i;
2322 static const DWORD pixel_shader_code[] =
2324 0xffff0101, /* ps_1_1*/
2325 0x00000042, 0xb00f0000, /* tex t0*/
2326 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2327 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2328 0x0000ffff
2330 static const DWORD double_texbem_code[] =
2332 0xffff0103, /* ps_1_3 */
2333 0x00000042, 0xb00f0000, /* tex t0 */
2334 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2335 0x00000042, 0xb00f0002, /* tex t2 */
2336 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2337 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2338 0x0000ffff /* end */
2340 static const float quad[][7] =
2342 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2343 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2344 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2345 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2347 static const float quad_proj[][9] =
2349 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2350 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2351 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2352 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2354 static const float double_quad[] =
2356 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2357 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2358 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2359 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2361 static const D3DVERTEXELEMENT9 decl_elements[][4] =
2364 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2365 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2366 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2367 D3DDECL_END()
2370 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2371 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2372 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2373 D3DDECL_END()
2377 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2378 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2379 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2380 ok(!!d3d, "Failed to create a D3D object.\n");
2381 if (!(device = create_device(d3d, window, window, TRUE)))
2383 skip("Failed to create a D3D device, skipping tests.\n");
2384 goto done;
2387 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2388 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2389 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2391 skip("No ps_1_1 support, skipping tests.\n");
2392 IDirect3DDevice9_Release(device);
2393 goto done;
2396 generate_bumpmap_textures(device);
2398 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2399 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2400 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2401 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2402 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2404 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2405 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2407 for(i=0; i<2; i++)
2409 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2410 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2412 if(i)
2414 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2415 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2418 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2419 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2420 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2421 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2423 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2424 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2425 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2426 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2428 hr = IDirect3DDevice9_BeginScene(device);
2429 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2431 if(!i)
2432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2433 else
2434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2435 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2437 hr = IDirect3DDevice9_EndScene(device);
2438 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2440 /* The Window 8 testbot (WARP) seems to use the transposed
2441 * D3DTSS_BUMPENVMAT matrix. */
2442 color = getPixelColor(device, 160, 240);
2443 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
2444 "Got unexpected color 0x%08x.\n", color);
2445 color = getPixelColor(device, 480, 240);
2446 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
2447 "Got unexpected color 0x%08x.\n", color);
2448 color = getPixelColor(device, 320, 120);
2449 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
2450 "Got unexpected color 0x%08x.\n", color);
2451 color = getPixelColor(device, 320, 360);
2452 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
2453 "Got unexpected color 0x%08x.\n", color);
2455 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2456 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2458 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2459 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2460 IDirect3DPixelShader9_Release(pixel_shader);
2462 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2463 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2464 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2467 /* clean up */
2468 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2469 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2471 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2472 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2474 for(i=0; i<2; i++)
2476 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2477 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2478 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2479 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2480 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2481 IDirect3DTexture9_Release(texture);
2484 /* Test double texbem */
2485 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2486 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2487 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2488 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2489 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2490 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2491 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2492 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2494 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2495 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2496 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2497 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2499 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2500 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2502 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2503 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2504 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2505 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2506 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2507 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2510 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2511 #define tex 0x00ff0000
2512 #define tex1 0x0000ff00
2513 #define origin 0x000000ff
2514 static const DWORD pixel_data[] = {
2515 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2516 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2517 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2518 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2519 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2520 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2521 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2522 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2524 #undef tex1
2525 #undef tex2
2526 #undef origin
2528 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2529 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2530 for(i = 0; i < 8; i++) {
2531 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2533 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2534 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2537 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2538 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2539 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2540 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2541 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2542 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2543 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2544 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2545 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2546 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2547 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2548 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2550 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2551 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2552 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2553 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2554 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2555 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2556 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2557 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2558 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2559 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2561 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2562 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2563 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2564 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2565 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2566 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2567 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2568 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2569 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2570 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2572 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2573 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2574 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2575 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2576 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2577 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2578 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2579 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2580 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2581 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2582 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2583 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2584 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2585 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2586 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2587 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2589 hr = IDirect3DDevice9_BeginScene(device);
2590 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2592 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
2593 hr = IDirect3DDevice9_EndScene(device);
2594 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2595 /* The Window 8 testbot (WARP) seems to use the transposed
2596 * D3DTSS_BUMPENVMAT matrix. */
2597 color = getPixelColor(device, 320, 240);
2598 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
2599 "Got unexpected color 0x%08x.\n", color);
2601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2602 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2604 IDirect3DPixelShader9_Release(pixel_shader);
2605 IDirect3DTexture9_Release(texture);
2606 IDirect3DTexture9_Release(texture1);
2607 IDirect3DTexture9_Release(texture2);
2608 refcount = IDirect3DDevice9_Release(device);
2609 ok(!refcount, "Device has %u references left.\n", refcount);
2610 done:
2611 IDirect3D9_Release(d3d);
2612 DestroyWindow(window);
2615 static void z_range_test(void)
2617 IDirect3DVertexShader9 *shader;
2618 IDirect3DDevice9 *device;
2619 IDirect3D9 *d3d;
2620 ULONG refcount;
2621 D3DCAPS9 caps;
2622 DWORD color;
2623 HWND window;
2624 HRESULT hr;
2626 static const struct
2628 struct vec3 position;
2629 DWORD diffuse;
2631 quad[] =
2633 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2634 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2635 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2636 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2638 quad2[] =
2640 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2641 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2642 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2643 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2645 static const struct
2647 struct vec4 position;
2648 DWORD diffuse;
2650 quad3[] =
2652 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2653 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2654 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2655 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2657 quad4[] =
2659 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2660 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2661 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2662 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2664 static const DWORD shader_code[] =
2666 0xfffe0101, /* vs_1_1 */
2667 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2668 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2669 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2670 0x0000ffff /* end */
2672 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2673 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2675 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2676 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2677 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2678 ok(!!d3d, "Failed to create a D3D object.\n");
2679 if (!(device = create_device(d3d, window, window, TRUE)))
2681 skip("Failed to create a D3D device, skipping tests.\n");
2682 goto done;
2685 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2686 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2688 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2689 * then call Present. Then clear the color buffer to make sure it has some defined content
2690 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2691 * by the depth value. */
2692 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2693 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2695 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2696 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2697 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2700 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
2701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2702 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2703 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2704 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2706 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2708 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2709 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2710 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2712 hr = IDirect3DDevice9_BeginScene(device);
2713 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2715 /* Test the untransformed vertex path */
2716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2717 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2719 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2721 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2723 /* Test the transformed vertex path */
2724 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2725 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2728 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2730 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2732 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2734 hr = IDirect3DDevice9_EndScene(device);
2735 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2737 /* Do not test the exact corner pixels, but go pretty close to them */
2739 /* Clipped because z > 1.0 */
2740 color = getPixelColor(device, 28, 238);
2741 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2742 color = getPixelColor(device, 28, 241);
2743 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2744 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2745 else
2746 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2748 /* Not clipped, > z buffer clear value(0.75).
2750 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2751 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2752 * equal to a stored depth buffer value of 0.5. */
2753 color = getPixelColor(device, 31, 238);
2754 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2755 color = getPixelColor(device, 31, 241);
2756 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2757 color = getPixelColor(device, 100, 238);
2758 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2759 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2760 color = getPixelColor(device, 100, 241);
2761 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2762 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2764 /* Not clipped, < z buffer clear value */
2765 color = getPixelColor(device, 104, 238);
2766 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2767 color = getPixelColor(device, 104, 241);
2768 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2769 color = getPixelColor(device, 318, 238);
2770 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2771 color = getPixelColor(device, 318, 241);
2772 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2774 /* Clipped because z < 0.0 */
2775 color = getPixelColor(device, 321, 238);
2776 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2777 color = getPixelColor(device, 321, 241);
2778 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2779 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2780 else
2781 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2783 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2784 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2786 /* Test the shader path */
2787 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2789 skip("Vertex shaders not supported, skipping tests.\n");
2790 IDirect3DDevice9_Release(device);
2791 goto done;
2793 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2794 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2797 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2799 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2800 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2801 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2802 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2804 hr = IDirect3DDevice9_BeginScene(device);
2805 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2807 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
2808 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2810 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2813 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2814 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
2815 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2817 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2819 hr = IDirect3DDevice9_EndScene(device);
2820 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2822 IDirect3DVertexShader9_Release(shader);
2824 /* Z < 1.0 */
2825 color = getPixelColor(device, 28, 238);
2826 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2828 /* 1.0 < z < 0.75 */
2829 color = getPixelColor(device, 31, 238);
2830 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2831 color = getPixelColor(device, 100, 238);
2832 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2833 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2835 /* 0.75 < z < 0.0 */
2836 color = getPixelColor(device, 104, 238);
2837 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2838 color = getPixelColor(device, 318, 238);
2839 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2841 /* 0.0 < z */
2842 color = getPixelColor(device, 321, 238);
2843 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2845 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2846 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2848 refcount = IDirect3DDevice9_Release(device);
2849 ok(!refcount, "Device has %u references left.\n", refcount);
2850 done:
2851 IDirect3D9_Release(d3d);
2852 DestroyWindow(window);
2855 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
2857 D3DSURFACE_DESC desc;
2858 D3DLOCKED_RECT l;
2859 HRESULT hr;
2860 unsigned int x, y;
2861 DWORD *mem;
2863 memset(&desc, 0, sizeof(desc));
2864 memset(&l, 0, sizeof(l));
2865 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2866 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2867 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
2868 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2869 if(FAILED(hr)) return;
2871 for(y = 0; y < desc.Height; y++)
2873 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2874 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2876 mem[x] = color;
2879 hr = IDirect3DSurface9_UnlockRect(surface);
2880 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2883 static void stretchrect_test(void)
2885 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
2886 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
2887 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
2888 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
2889 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
2890 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
2891 IDirect3DSurface9 *surf_temp32, *surf_temp64;
2892 IDirect3DSurface9 *backbuffer;
2893 IDirect3DDevice9 *device;
2894 IDirect3D9 *d3d;
2895 D3DCOLOR color;
2896 ULONG refcount;
2897 HWND window;
2898 HRESULT hr;
2900 static const RECT src_rect = {0, 0, 640, 480};
2901 static const RECT src_rect_flipy = {0, 480, 640, 0};
2902 static const RECT dst_rect = {0, 0, 640, 480};
2903 static const RECT dst_rect_flipy = {0, 480, 640, 0};
2904 static const RECT src_rect64 = {0, 0, 64, 64};
2905 static const RECT src_rect64_flipy = {0, 64, 64, 0};
2906 static const RECT dst_rect64 = {0, 0, 64, 64};
2907 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
2909 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2910 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2911 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2912 ok(!!d3d, "Failed to create a D3D object.\n");
2913 if (!(device = create_device(d3d, window, window, TRUE)))
2915 skip("Failed to create a D3D device, skipping tests.\n");
2916 goto done;
2919 /* Create our temporary surfaces in system memory. */
2920 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
2921 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2922 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
2923 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
2924 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2925 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
2927 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
2928 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
2929 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2930 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
2931 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
2932 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2933 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
2934 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
2935 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2936 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
2938 /* Create render target surfaces. */
2939 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
2940 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2941 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2942 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
2943 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2944 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2945 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
2946 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2947 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
2948 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2949 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2951 /* Create render target textures. */
2952 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
2953 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2954 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2955 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
2956 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2957 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2958 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
2959 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2960 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2961 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
2962 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2963 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2964 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2965 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2966 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2967 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2968 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2969 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2970 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2971 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2973 /* Create regular textures in D3DPOOL_DEFAULT. */
2974 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2975 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2976 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2977 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2978 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2979 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2980 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2981 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2982 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2983 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2984 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2985 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
2987 /**********************************************************************
2988 * Tests for when the source parameter is an offscreen plain surface. *
2989 **********************************************************************/
2991 /* Fill the offscreen 64x64 surface with green. */
2992 fill_surface(surf_offscreen64, 0xff00ff00, 0);
2994 /* offscreenplain ==> offscreenplain, same size. */
2995 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
2996 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2997 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2998 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
2999 /* Blit without scaling. */
3000 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3001 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3002 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3003 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3004 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3005 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3006 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3007 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3008 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3009 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3010 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3012 /* offscreenplain ==> rendertarget texture, same size. */
3013 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3014 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3015 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3016 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3017 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3018 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3019 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3020 /* Blit without scaling. */
3021 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3022 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3023 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3024 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3025 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3026 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3027 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3028 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3029 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3030 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3031 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3033 /* offscreenplain ==> rendertarget surface, same size. */
3034 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3035 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3036 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3037 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3038 /* Blit without scaling. */
3039 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3040 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3041 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3042 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3043 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3044 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3045 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3046 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3047 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3048 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3049 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3051 /* offscreenplain ==> texture, same size (should fail). */
3052 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3053 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3055 /* Fill the smaller offscreen surface with red. */
3056 fill_surface(surf_offscreen32, 0xffff0000, 0);
3058 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3059 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3060 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3062 /* offscreenplain ==> rendertarget texture, scaling. */
3063 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3064 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3065 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3066 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3067 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3068 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3069 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3071 /* offscreenplain ==> rendertarget surface, scaling. */
3072 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3073 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3074 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3075 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3077 /* offscreenplain ==> texture, scaling (should fail). */
3078 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3079 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3081 /*************************************************************
3082 * Tests for when the source parameter is a regular texture. *
3083 *************************************************************/
3085 /* Fill the surface of the regular texture with blue. */
3086 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3087 fill_surface(surf_temp64, 0xff0000ff, 0);
3088 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3089 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3091 /* texture ==> offscreenplain, same size. */
3092 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3093 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3095 /* texture ==> rendertarget texture, same size. */
3096 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3097 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3098 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3099 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3100 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3101 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3102 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3103 /* Blit without scaling. */
3104 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3105 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3106 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3107 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3108 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3109 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3110 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3111 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3112 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3113 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3114 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3116 /* texture ==> rendertarget surface, same size. */
3117 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3118 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3119 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3120 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3121 /* Blit without scaling. */
3122 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3123 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3124 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3125 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3126 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3127 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3128 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3129 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3130 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3131 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3132 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3134 /* texture ==> texture, same size (should fail). */
3135 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3136 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3138 /* Fill the surface of the smaller regular texture with red. */
3139 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3140 fill_surface(surf_temp32, 0xffff0000, 0);
3141 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3142 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3144 /* texture ==> offscreenplain, scaling (should fail). */
3145 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3146 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3148 /* texture ==> rendertarget texture, scaling. */
3149 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3150 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3151 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3152 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3153 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3154 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3155 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3157 /* texture ==> rendertarget surface, scaling. */
3158 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3159 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3160 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3161 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3163 /* texture ==> texture, scaling (should fail). */
3164 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3165 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3167 /******************************************************************
3168 * Tests for when the source parameter is a rendertarget texture. *
3169 ******************************************************************/
3171 /* Fill the surface of the rendertarget texture with white. */
3172 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3173 fill_surface(surf_temp64, 0xffffffff, 0);
3174 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3175 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3177 /* rendertarget texture ==> offscreenplain, same size. */
3178 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3179 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3181 /* rendertarget texture ==> rendertarget texture, same size. */
3182 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3183 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3184 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3185 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3186 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3187 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3188 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3189 /* Blit without scaling. */
3190 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3191 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3192 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3193 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3194 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3195 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3196 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3197 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3198 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3199 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3200 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3202 /* rendertarget texture ==> rendertarget surface, same size. */
3203 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3204 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3205 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3206 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3207 /* Blit without scaling. */
3208 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3209 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3210 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3211 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3212 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3213 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3214 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3215 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3216 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3217 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3218 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3220 /* rendertarget texture ==> texture, same size (should fail). */
3221 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3222 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3224 /* Fill the surface of the smaller rendertarget texture with red. */
3225 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3226 fill_surface(surf_temp32, 0xffff0000, 0);
3227 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3228 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3230 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3231 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3232 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3234 /* rendertarget texture ==> rendertarget texture, scaling. */
3235 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3236 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3237 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3238 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3239 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3240 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3241 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3243 /* rendertarget texture ==> rendertarget surface, scaling. */
3244 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3245 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3246 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3247 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3249 /* rendertarget texture ==> texture, scaling (should fail). */
3250 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3251 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3253 /******************************************************************
3254 * Tests for when the source parameter is a rendertarget surface. *
3255 ******************************************************************/
3257 /* Fill the surface of the rendertarget surface with black. */
3258 fill_surface(surf_rt64, 0xff000000, 0);
3260 /* rendertarget texture ==> offscreenplain, same size. */
3261 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3262 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3264 /* rendertarget surface ==> rendertarget texture, same size. */
3265 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3266 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3267 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3268 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3269 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3270 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3271 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3272 /* Blit without scaling. */
3273 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3274 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3275 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3276 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3277 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3278 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3279 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3280 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3281 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3282 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3283 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3285 /* rendertarget surface ==> rendertarget surface, same size. */
3286 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3287 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3288 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3289 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3290 /* Blit without scaling. */
3291 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3292 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3293 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3294 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3295 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3296 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3297 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3298 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3299 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3300 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3301 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3303 /* rendertarget surface ==> texture, same size (should fail). */
3304 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3305 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3307 /* Fill the surface of the smaller rendertarget texture with red. */
3308 fill_surface(surf_rt32, 0xffff0000, 0);
3310 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3311 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3312 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3314 /* rendertarget surface ==> rendertarget texture, scaling. */
3315 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3316 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3317 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3318 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3319 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3320 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3321 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3323 /* rendertarget surface ==> rendertarget surface, scaling. */
3324 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3325 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3326 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3327 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3329 /* rendertarget surface ==> texture, scaling (should fail). */
3330 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3331 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3333 /* backbuffer ==> surface tests (no scaling). */
3334 /* Blit with NULL rectangles. */
3335 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
3336 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3337 /* Blit without scaling. */
3338 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
3339 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
3340 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3341 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3342 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
3343 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
3344 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3345 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3346 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
3347 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
3348 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3350 /* TODO: Test format conversions. */
3352 IDirect3DSurface9_Release(backbuffer);
3353 IDirect3DSurface9_Release(surf_rt32);
3354 IDirect3DSurface9_Release(surf_rt64);
3355 IDirect3DSurface9_Release(surf_rt_dest64);
3356 IDirect3DSurface9_Release(surf_temp32);
3357 IDirect3DSurface9_Release(surf_temp64);
3358 IDirect3DSurface9_Release(surf_offscreen32);
3359 IDirect3DSurface9_Release(surf_offscreen64);
3360 IDirect3DSurface9_Release(surf_offscreen_dest64);
3361 IDirect3DSurface9_Release(surf_tex_rt32);
3362 IDirect3DTexture9_Release(tex_rt32);
3363 IDirect3DSurface9_Release(surf_tex_rt64);
3364 IDirect3DTexture9_Release(tex_rt64);
3365 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3366 IDirect3DTexture9_Release(tex_rt_dest64);
3367 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3368 IDirect3DTexture9_Release(tex_rt_dest640_480);
3369 IDirect3DSurface9_Release(surf_tex32);
3370 IDirect3DTexture9_Release(tex32);
3371 IDirect3DSurface9_Release(surf_tex64);
3372 IDirect3DTexture9_Release(tex64);
3373 IDirect3DSurface9_Release(surf_tex_dest64);
3374 IDirect3DTexture9_Release(tex_dest64);
3375 refcount = IDirect3DDevice9_Release(device);
3376 ok(!refcount, "Device has %u references left.\n", refcount);
3377 done:
3378 IDirect3D9_Release(d3d);
3379 DestroyWindow(window);
3382 static void maxmip_test(void)
3384 IDirect3DTexture9 *texture;
3385 IDirect3DSurface9 *surface;
3386 IDirect3DDevice9 *device;
3387 IDirect3D9 *d3d;
3388 D3DCOLOR color;
3389 ULONG refcount;
3390 D3DCAPS9 caps;
3391 HWND window;
3392 HRESULT hr;
3393 DWORD ret;
3395 static const struct
3397 struct
3399 float x, y, z;
3400 float s, t;
3402 v[4];
3404 quads[] =
3407 {-1.0, -1.0, 0.0, 0.0, 0.0},
3408 {-1.0, 0.0, 0.0, 0.0, 1.0},
3409 { 0.0, -1.0, 0.0, 1.0, 0.0},
3410 { 0.0, 0.0, 0.0, 1.0, 1.0},
3413 { 0.0, -1.0, 0.0, 0.0, 0.0},
3414 { 0.0, 0.0, 0.0, 0.0, 1.0},
3415 { 1.0, -1.0, 0.0, 1.0, 0.0},
3416 { 1.0, 0.0, 0.0, 1.0, 1.0},
3419 { 0.0, 0.0, 0.0, 0.0, 0.0},
3420 { 0.0, 1.0, 0.0, 0.0, 1.0},
3421 { 1.0, 0.0, 0.0, 1.0, 0.0},
3422 { 1.0, 1.0, 0.0, 1.0, 1.0},
3425 {-1.0, 0.0, 0.0, 0.0, 0.0},
3426 {-1.0, 1.0, 0.0, 0.0, 1.0},
3427 { 0.0, 0.0, 0.0, 1.0, 0.0},
3428 { 0.0, 1.0, 0.0, 1.0, 1.0},
3432 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3433 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3434 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3435 ok(!!d3d, "Failed to create a D3D object.\n");
3436 if (!(device = create_device(d3d, window, window, TRUE)))
3438 skip("Failed to create a D3D device, skipping tests.\n");
3439 goto done;
3442 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3443 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3444 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
3446 skip("No mipmap support, skipping tests.\n");
3447 IDirect3DDevice9_Release(device);
3448 goto done;
3451 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
3452 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
3453 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3455 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3456 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3457 fill_surface(surface, 0xffff0000, 0);
3458 IDirect3DSurface9_Release(surface);
3459 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3460 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3461 fill_surface(surface, 0xff00ff00, 0);
3462 IDirect3DSurface9_Release(surface);
3463 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3464 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3465 fill_surface(surface, 0xff0000ff, 0);
3466 IDirect3DSurface9_Release(surface);
3468 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3470 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3471 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3474 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3475 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3476 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3478 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3479 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3481 hr = IDirect3DDevice9_BeginScene(device);
3482 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3484 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3485 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3489 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3490 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3492 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3494 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3495 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3497 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3499 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3500 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3501 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3502 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3504 hr = IDirect3DDevice9_EndScene(device);
3505 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3507 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3508 color = getPixelColor(device, 160, 360);
3509 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3510 color = getPixelColor(device, 480, 360);
3511 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3512 color = getPixelColor(device, 480, 120);
3513 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3514 color = getPixelColor(device, 160, 120);
3515 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3516 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3517 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3519 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3520 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3523 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3525 hr = IDirect3DDevice9_BeginScene(device);
3526 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3528 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3529 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3531 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3533 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3534 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3536 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3538 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3539 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3541 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3543 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3544 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3546 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3548 hr = IDirect3DDevice9_EndScene(device);
3549 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3551 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3552 * level 3 (> levels in texture) samples from the highest level in the
3553 * texture (level 2). */
3554 color = getPixelColor(device, 160, 360);
3555 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3556 color = getPixelColor(device, 480, 360);
3557 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3558 color = getPixelColor(device, 480, 120);
3559 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3560 color = getPixelColor(device, 160, 120);
3561 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3562 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3563 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3566 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3568 hr = IDirect3DDevice9_BeginScene(device);
3569 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3571 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3572 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3573 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3574 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3575 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3576 ret = IDirect3DTexture9_SetLOD(texture, 1);
3577 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
3578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3579 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3581 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3582 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3583 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3584 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3585 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3586 ret = IDirect3DTexture9_SetLOD(texture, 2);
3587 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
3588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3589 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3591 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3592 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3593 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3594 ret = IDirect3DTexture9_SetLOD(texture, 1);
3595 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
3596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3597 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3599 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3600 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3601 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3602 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3603 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
3604 ret = IDirect3DTexture9_SetLOD(texture, 1);
3605 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
3606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3607 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3609 hr = IDirect3DDevice9_EndScene(device);
3610 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3612 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3613 * level 3 (> levels in texture) samples from the highest level in the
3614 * texture (level 2). */
3615 color = getPixelColor(device, 160, 360);
3616 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3617 color = getPixelColor(device, 480, 360);
3618 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3619 color = getPixelColor(device, 480, 120);
3620 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3621 color = getPixelColor(device, 160, 120);
3622 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3624 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3625 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3627 IDirect3DTexture9_Release(texture);
3628 refcount = IDirect3DDevice9_Release(device);
3629 ok(!refcount, "Device has %u references left.\n", refcount);
3630 done:
3631 IDirect3D9_Release(d3d);
3632 DestroyWindow(window);
3635 static void release_buffer_test(void)
3637 IDirect3DVertexBuffer9 *vb;
3638 IDirect3DIndexBuffer9 *ib;
3639 IDirect3DDevice9 *device;
3640 IDirect3D9 *d3d;
3641 D3DCOLOR color;
3642 ULONG refcount;
3643 HWND window;
3644 HRESULT hr;
3645 BYTE *data;
3646 LONG ref;
3648 static const short indices[] = {3, 4, 5};
3649 static const struct
3651 struct vec3 position;
3652 DWORD diffuse;
3654 quad[] =
3656 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
3657 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
3658 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
3660 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
3661 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
3662 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
3665 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3666 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3667 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3668 ok(!!d3d, "Failed to create a D3D object.\n");
3669 if (!(device = create_device(d3d, window, window, TRUE)))
3671 skip("Failed to create a D3D device, skipping tests.\n");
3672 goto done;
3675 /* Index and vertex buffers should always be creatable */
3676 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
3677 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
3678 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3679 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3680 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3681 memcpy(data, quad, sizeof(quad));
3682 hr = IDirect3DVertexBuffer9_Unlock(vb);
3683 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3685 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
3686 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3687 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
3688 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3689 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3690 memcpy(data, indices, sizeof(indices));
3691 hr = IDirect3DIndexBuffer9_Unlock(ib);
3692 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3694 hr = IDirect3DDevice9_SetIndices(device, ib);
3695 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3696 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3697 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3698 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3699 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3701 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3703 /* Now destroy the bound index buffer and draw again */
3704 ref = IDirect3DIndexBuffer9_Release(ib);
3705 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3707 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3708 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3710 hr = IDirect3DDevice9_BeginScene(device);
3711 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3712 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
3713 * D3D from making assumptions about the indices or vertices. */
3714 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3715 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3716 hr = IDirect3DDevice9_EndScene(device);
3717 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3719 color = getPixelColor(device, 160, 120);
3720 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
3721 color = getPixelColor(device, 480, 360);
3722 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
3724 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3725 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3727 /* Index buffer was already destroyed as part of the test */
3728 IDirect3DVertexBuffer9_Release(vb);
3729 refcount = IDirect3DDevice9_Release(device);
3730 ok(!refcount, "Device has %u references left.\n", refcount);
3731 done:
3732 IDirect3D9_Release(d3d);
3733 DestroyWindow(window);
3736 static void float_texture_test(void)
3738 IDirect3DTexture9 *texture;
3739 IDirect3DDevice9 *device;
3740 D3DLOCKED_RECT lr;
3741 IDirect3D9 *d3d;
3742 ULONG refcount;
3743 float *data;
3744 DWORD color;
3745 HWND window;
3746 HRESULT hr;
3748 static const float quad[] =
3750 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
3751 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
3752 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
3753 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
3756 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3757 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3758 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3759 ok(!!d3d, "Failed to create a D3D object.\n");
3760 if (!(device = create_device(d3d, window, window, TRUE)))
3762 skip("Failed to create a D3D device, skipping tests.\n");
3763 goto done;
3766 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
3767 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
3769 skip("D3DFMT_R32F textures not supported\n");
3770 IDirect3DDevice9_Release(device);
3771 goto done;
3774 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
3775 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3777 memset(&lr, 0, sizeof(lr));
3778 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3779 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3780 data = lr.pBits;
3781 *data = 0.0;
3782 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3783 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3786 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3787 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
3788 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3790 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3791 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3793 hr = IDirect3DDevice9_BeginScene(device);
3794 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3795 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3796 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3798 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3799 hr = IDirect3DDevice9_EndScene(device);
3800 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3802 color = getPixelColor(device, 240, 320);
3803 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
3805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3806 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3808 IDirect3DTexture9_Release(texture);
3809 refcount = IDirect3DDevice9_Release(device);
3810 ok(!refcount, "Device has %u references left.\n", refcount);
3811 done:
3812 IDirect3D9_Release(d3d);
3813 DestroyWindow(window);
3816 static void g16r16_texture_test(void)
3818 IDirect3DTexture9 *texture;
3819 IDirect3DDevice9 *device;
3820 D3DLOCKED_RECT lr;
3821 IDirect3D9 *d3d;
3822 ULONG refcount;
3823 DWORD *data;
3824 DWORD color;
3825 HWND window;
3826 HRESULT hr;
3828 static const float quad[] =
3830 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
3831 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
3832 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
3833 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
3836 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3837 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3838 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3839 ok(!!d3d, "Failed to create a D3D object.\n");
3840 if (!(device = create_device(d3d, window, window, TRUE)))
3842 skip("Failed to create a D3D device, skipping tests.\n");
3843 goto done;
3846 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
3847 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
3849 skip("D3DFMT_G16R16 textures not supported\n");
3850 IDirect3DDevice9_Release(device);
3851 goto done;
3854 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
3855 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3857 memset(&lr, 0, sizeof(lr));
3858 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3859 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3860 data = lr.pBits;
3861 *data = 0x0f00f000;
3862 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3863 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3866 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3867 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
3868 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3870 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3871 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3873 hr = IDirect3DDevice9_BeginScene(device);
3874 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3875 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3876 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3878 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3879 hr = IDirect3DDevice9_EndScene(device);
3880 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3882 color = getPixelColor(device, 240, 320);
3883 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3884 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3886 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3887 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3889 IDirect3DTexture9_Release(texture);
3890 refcount = IDirect3DDevice9_Release(device);
3891 ok(!refcount, "Device has %u references left.\n", refcount);
3892 done:
3893 IDirect3D9_Release(d3d);
3894 DestroyWindow(window);
3897 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3899 LONG x_coords[2][2] =
3901 {r.left - 1, r.left + 1},
3902 {r.right + 1, r.right - 1},
3904 LONG y_coords[2][2] =
3906 {r.top - 1, r.top + 1},
3907 {r.bottom + 1, r.bottom - 1}
3909 unsigned int i, j, x_side, y_side;
3911 for (i = 0; i < 2; ++i)
3913 for (j = 0; j < 2; ++j)
3915 for (x_side = 0; x_side < 2; ++x_side)
3917 for (y_side = 0; y_side < 2; ++y_side)
3919 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3920 DWORD color;
3921 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3923 color = getPixelColor(device, x, y);
3924 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3925 message, x, y, color, expected);
3932 struct projected_textures_test_run
3934 const char *message;
3935 DWORD flags;
3936 IDirect3DVertexDeclaration9 *decl;
3937 BOOL vs, ps;
3938 RECT rect;
3941 static void projected_textures_test(IDirect3DDevice9 *device,
3942 struct projected_textures_test_run tests[4])
3944 unsigned int i;
3946 static const DWORD vertex_shader[] =
3948 0xfffe0101, /* vs_1_1 */
3949 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3950 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
3951 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3952 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
3953 0x0000ffff /* end */
3955 static const DWORD pixel_shader[] =
3957 0xffff0103, /* ps_1_3 */
3958 0x00000042, 0xb00f0000, /* tex t0 */
3959 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3960 0x0000ffff /* end */
3962 IDirect3DVertexShader9 *vs = NULL;
3963 IDirect3DPixelShader9 *ps = NULL;
3964 IDirect3D9 *d3d;
3965 D3DCAPS9 caps;
3966 HRESULT hr;
3968 IDirect3DDevice9_GetDirect3D(device, &d3d);
3969 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3970 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
3971 IDirect3D9_Release(d3d);
3973 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
3975 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
3976 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
3978 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
3980 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
3981 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3984 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
3985 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3987 hr = IDirect3DDevice9_BeginScene(device);
3988 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3990 for (i = 0; i < 4; ++i)
3992 DWORD value = 0xdeadbeef;
3993 static const float proj_quads[] =
3995 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
3996 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
3997 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
3998 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4000 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4001 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4002 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4003 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4005 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4006 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4007 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4008 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4010 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4011 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4012 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4013 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4016 if (tests[i].vs)
4018 if (!vs)
4020 skip("Vertex shaders not supported, skipping\n");
4021 continue;
4023 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4025 else
4026 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4027 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4028 if (tests[i].ps)
4030 if (!ps)
4032 skip("Pixel shaders not supported, skipping\n");
4033 continue;
4035 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4037 else
4038 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4039 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4041 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4042 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4045 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4046 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4047 ok(SUCCEEDED(hr) && value == tests[i].flags,
4048 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4051 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4052 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4055 hr = IDirect3DDevice9_EndScene(device);
4056 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4058 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4059 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4060 if (vs) IDirect3DVertexShader9_Release(vs);
4061 if (ps) IDirect3DPixelShader9_Release(ps);
4063 for (i = 0; i < 4; ++i)
4065 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4066 check_rect(device, tests[i].rect, tests[i].message);
4069 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4070 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4073 static void texture_transform_flags_test(void)
4075 HRESULT hr;
4076 IDirect3D9 *d3d;
4077 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4078 D3DCAPS9 caps;
4079 IDirect3DTexture9 *texture = NULL;
4080 IDirect3DVolumeTexture9 *volume = NULL;
4081 IDirect3DDevice9 *device;
4082 unsigned int x, y, z;
4083 D3DLOCKED_RECT lr;
4084 D3DLOCKED_BOX lb;
4085 D3DCOLOR color;
4086 ULONG refcount;
4087 HWND window;
4088 UINT w, h;
4089 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4091 static const D3DVERTEXELEMENT9 decl_elements[] = {
4092 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4093 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4094 D3DDECL_END()
4096 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4097 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4098 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4099 D3DDECL_END()
4101 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4102 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4103 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4104 D3DDECL_END()
4106 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4107 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4108 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4109 D3DDECL_END()
4111 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4112 0x00, 0xff, 0x00, 0x00,
4113 0x00, 0x00, 0x00, 0x00,
4114 0x00, 0x00, 0x00, 0x00};
4115 static const D3DMATRIX identity =
4117 1.0f, 0.0f, 0.0f, 0.0f,
4118 0.0f, 1.0f, 0.0f, 0.0f,
4119 0.0f, 0.0f, 1.0f, 0.0f,
4120 0.0f, 0.0f, 0.0f, 1.0f,
4121 }}};
4123 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4124 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4125 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4126 ok(!!d3d, "Failed to create a D3D object.\n");
4127 if (!(device = create_device(d3d, window, window, TRUE)))
4129 skip("Failed to create a D3D device, skipping tests.\n");
4130 goto done;
4133 memset(&lr, 0, sizeof(lr));
4134 memset(&lb, 0, sizeof(lb));
4135 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4136 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4137 fmt = D3DFMT_A16B16G16R16;
4139 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4140 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4141 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4142 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4143 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4145 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4146 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4147 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4148 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4149 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4153 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4154 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4155 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4156 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4157 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4158 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4161 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4163 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4164 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4168 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4170 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4172 w = min(1024, caps.MaxTextureWidth);
4173 h = min(1024, caps.MaxTextureHeight);
4174 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4175 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4176 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4177 if (!texture)
4179 skip("Failed to create the test texture.\n");
4180 IDirect3DDevice9_Release(device);
4181 goto done;
4184 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4185 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4186 * 1.0 in red and green for the x and y coords
4188 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4189 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4190 for(y = 0; y < h; y++) {
4191 for(x = 0; x < w; x++) {
4192 double r_f = (double) y / (double) h;
4193 double g_f = (double) x / (double) w;
4194 if(fmt == D3DFMT_A16B16G16R16) {
4195 unsigned short r, g;
4196 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4197 r = (unsigned short) (r_f * 65536.0);
4198 g = (unsigned short) (g_f * 65536.0);
4199 dst[0] = r;
4200 dst[1] = g;
4201 dst[2] = 0;
4202 dst[3] = 65535;
4203 } else {
4204 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4205 unsigned char r = (unsigned char) (r_f * 255.0);
4206 unsigned char g = (unsigned char) (g_f * 255.0);
4207 dst[0] = 0;
4208 dst[1] = g;
4209 dst[2] = r;
4210 dst[3] = 255;
4214 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4215 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4216 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4217 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4219 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4220 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4221 hr = IDirect3DDevice9_BeginScene(device);
4222 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4223 if(SUCCEEDED(hr))
4225 static const float quad1[] =
4227 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4228 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4229 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4230 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4232 static const float quad2[] =
4234 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4235 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4236 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4237 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4239 static const float quad3[] =
4241 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4242 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4243 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4244 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4246 static const float quad4[] =
4248 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4249 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4250 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4251 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4253 D3DMATRIX mat =
4255 0.0f, 0.0f, 0.0f, 0.0f,
4256 0.0f, 0.0f, 0.0f, 0.0f,
4257 0.0f, 0.0f, 0.0f, 0.0f,
4258 0.0f, 0.0f, 0.0f, 0.0f,
4259 }}};
4261 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4262 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4265 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4267 /* What happens with transforms enabled? */
4268 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4269 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4271 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4273 /* What happens if 4 coords are used, but only 2 given ?*/
4274 U(mat).m[2][0] = 1.0f;
4275 U(mat).m[3][1] = 1.0f;
4276 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4277 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4278 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4279 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4281 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4283 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4284 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4285 * due to the coords in the vertices. (turns out red, indeed)
4287 memset(&mat, 0, sizeof(mat));
4288 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4289 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4290 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4292 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4293 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4295 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4297 hr = IDirect3DDevice9_EndScene(device);
4298 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4300 color = getPixelColor(device, 160, 360);
4301 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4302 color = getPixelColor(device, 160, 120);
4303 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4304 color = getPixelColor(device, 480, 120);
4305 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4306 color = getPixelColor(device, 480, 360);
4307 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4308 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4309 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4312 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4314 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4315 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4316 hr = IDirect3DDevice9_BeginScene(device);
4317 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4318 if(SUCCEEDED(hr))
4320 static const float quad1[] =
4322 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4323 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4324 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4325 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4327 static const float quad2[] =
4329 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4330 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4331 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4332 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4334 static const float quad3[] =
4336 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4337 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4338 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4339 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4341 static const float quad4[] =
4343 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4344 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4345 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4346 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4348 D3DMATRIX mat =
4350 0.0f, 0.0f, 0.0f, 0.0f,
4351 0.0f, 0.0f, 0.0f, 0.0f,
4352 0.0f, 1.0f, 0.0f, 0.0f,
4353 0.0f, 0.0f, 0.0f, 0.0f,
4354 }}};
4356 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4357 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4358 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4359 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4360 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4363 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4365 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4366 * it behaves like COUNT2 because normal textures require 2 coords. */
4367 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4368 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4370 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4372 /* Just to be sure, the same as quad2 above */
4373 memset(&mat, 0, sizeof(mat));
4374 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4375 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4376 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4377 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4379 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4381 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4382 * used? And what happens to the first? */
4383 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4384 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4386 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4388 hr = IDirect3DDevice9_EndScene(device);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4391 color = getPixelColor(device, 160, 360);
4392 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4393 color = getPixelColor(device, 160, 120);
4394 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4395 color = getPixelColor(device, 480, 120);
4396 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4397 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4398 color = getPixelColor(device, 480, 360);
4399 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4400 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4401 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4402 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4404 IDirect3DTexture9_Release(texture);
4406 /* Test projected textures, without any fancy matrices */
4407 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4409 if (SUCCEEDED(hr))
4411 struct projected_textures_test_run projected_tests_1[4] =
4414 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4415 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4416 decl3,
4417 FALSE, TRUE,
4418 {120, 300, 240, 390},
4421 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4422 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4423 decl3,
4424 FALSE, TRUE,
4425 {400, 360, 480, 420},
4427 /* Try with some invalid values */
4429 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4430 0xffffffff,
4431 decl3,
4432 FALSE, TRUE,
4433 {120, 60, 240, 150}
4436 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4437 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4438 decl4,
4439 FALSE, TRUE,
4440 {340, 210, 360, 225},
4443 struct projected_textures_test_run projected_tests_2[4] =
4446 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4447 D3DTTFF_PROJECTED,
4448 decl3,
4449 FALSE, TRUE,
4450 {120, 300, 240, 390},
4453 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4454 D3DTTFF_PROJECTED,
4455 decl,
4456 FALSE, TRUE,
4457 {400, 360, 480, 420},
4460 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4461 0xffffffff,
4462 decl,
4463 FALSE, TRUE,
4464 {80, 120, 160, 180},
4467 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4468 D3DTTFF_COUNT1,
4469 decl4,
4470 FALSE, TRUE,
4471 {340, 210, 360, 225},
4474 struct projected_textures_test_run projected_tests_3[4] =
4477 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4478 D3DTTFF_PROJECTED,
4479 decl3,
4480 TRUE, FALSE,
4481 {120, 300, 240, 390},
4484 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4485 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4486 decl3,
4487 TRUE, TRUE,
4488 {440, 300, 560, 390},
4491 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4492 0xffffffff,
4493 decl3,
4494 TRUE, TRUE,
4495 {120, 60, 240, 150},
4498 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4499 D3DTTFF_PROJECTED,
4500 decl3,
4501 FALSE, FALSE,
4502 {440, 60, 560, 150},
4506 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
4507 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4509 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4510 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4511 for(x = 0; x < 4; x++) {
4512 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4514 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4515 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4516 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4517 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4519 projected_textures_test(device, projected_tests_1);
4520 projected_textures_test(device, projected_tests_2);
4521 projected_textures_test(device, projected_tests_3);
4523 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4524 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4525 IDirect3DTexture9_Release(texture);
4528 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4529 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4530 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4531 * Thus watch out if sampling from texels between 0 and 1.
4533 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4534 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4535 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4536 if(!volume) {
4537 skip("Failed to create a volume texture\n");
4538 goto out;
4541 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4542 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4543 for(z = 0; z < 32; z++) {
4544 for(y = 0; y < 32; y++) {
4545 for(x = 0; x < 32; x++) {
4546 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4547 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4548 float r_f = (float) x / 31.0;
4549 float g_f = (float) y / 31.0;
4550 float b_f = (float) z / 31.0;
4552 if(fmt == D3DFMT_A16B16G16R16) {
4553 unsigned short *mem_s = mem;
4554 mem_s[0] = r_f * 65535.0;
4555 mem_s[1] = g_f * 65535.0;
4556 mem_s[2] = b_f * 65535.0;
4557 mem_s[3] = 65535;
4558 } else {
4559 unsigned char *mem_c = mem;
4560 mem_c[0] = b_f * 255.0;
4561 mem_c[1] = g_f * 255.0;
4562 mem_c[2] = r_f * 255.0;
4563 mem_c[3] = 255;
4568 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4569 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4571 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4572 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4574 hr = IDirect3DDevice9_BeginScene(device);
4575 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4576 if(SUCCEEDED(hr))
4578 static const float quad1[] =
4580 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4581 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4582 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4583 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4585 static const float quad2[] =
4587 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4588 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4589 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4590 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4592 static const float quad3[] =
4594 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
4595 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
4596 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
4597 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
4599 static const float quad4[] =
4601 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4602 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4603 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4604 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4606 D3DMATRIX mat =
4608 1.0f, 0.0f, 0.0f, 0.0f,
4609 0.0f, 0.0f, 1.0f, 0.0f,
4610 0.0f, 1.0f, 0.0f, 0.0f,
4611 0.0f, 0.0f, 0.0f, 1.0f,
4612 }}};
4613 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4614 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4616 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4617 * values
4619 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4620 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4621 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4622 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4623 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4624 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4626 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4627 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4628 * otherwise the w will be missing(blue).
4629 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4630 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4631 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4632 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4634 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4636 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4637 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
4638 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4639 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4640 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4641 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4642 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4643 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4644 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4646 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4647 * disable. ATI extends it up to the amount of values needed for the volume texture
4649 memset(&mat, 0, sizeof(mat));
4650 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4651 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4652 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4653 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4654 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4655 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4657 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4659 hr = IDirect3DDevice9_EndScene(device);
4660 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4663 color = getPixelColor(device, 160, 360);
4664 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4665 color = getPixelColor(device, 160, 120);
4666 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4667 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4668 color = getPixelColor(device, 480, 120);
4669 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4670 color = getPixelColor(device, 480, 360);
4671 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4673 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4676 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4677 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4678 hr = IDirect3DDevice9_BeginScene(device);
4679 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4680 if(SUCCEEDED(hr))
4682 static const float quad1[] =
4684 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4685 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4686 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4687 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
4689 static const float quad2[] =
4691 -1.0f, 0.0f, 0.1f,
4692 -1.0f, 1.0f, 0.1f,
4693 0.0f, 0.0f, 0.1f,
4694 0.0f, 1.0f, 0.1f,
4696 static const float quad3[] =
4698 0.0f, 0.0f, 0.1f, 1.0f,
4699 0.0f, 1.0f, 0.1f, 1.0f,
4700 1.0f, 0.0f, 0.1f, 1.0f,
4701 1.0f, 1.0f, 0.1f, 1.0f,
4703 static const D3DMATRIX mat =
4705 0.0f, 0.0f, 0.0f, 0.0f,
4706 0.0f, 0.0f, 0.0f, 0.0f,
4707 0.0f, 0.0f, 0.0f, 0.0f,
4708 0.0f, 1.0f, 0.0f, 0.0f,
4709 }}};
4710 static const D3DMATRIX mat2 =
4712 0.0f, 0.0f, 0.0f, 1.0f,
4713 1.0f, 0.0f, 0.0f, 0.0f,
4714 0.0f, 1.0f, 0.0f, 0.0f,
4715 0.0f, 0.0f, 1.0f, 0.0f,
4716 }}};
4717 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4718 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4720 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4721 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4722 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4723 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4724 * 4th *input* coordinate.
4726 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4727 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4729 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4731 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4733 /* None passed */
4734 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
4735 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4736 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4737 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4738 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4739 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4741 /* 4 used, 1 passed */
4742 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4743 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4744 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4747 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4749 hr = IDirect3DDevice9_EndScene(device);
4750 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4752 color = getPixelColor(device, 160, 360);
4753 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4754 color = getPixelColor(device, 160, 120);
4755 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4756 color = getPixelColor(device, 480, 120);
4757 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4758 /* Quad4: unused */
4760 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4763 IDirect3DVolumeTexture9_Release(volume);
4765 out:
4766 IDirect3DVertexDeclaration9_Release(decl);
4767 IDirect3DVertexDeclaration9_Release(decl2);
4768 IDirect3DVertexDeclaration9_Release(decl3);
4769 IDirect3DVertexDeclaration9_Release(decl4);
4770 refcount = IDirect3DDevice9_Release(device);
4771 ok(!refcount, "Device has %u references left.\n", refcount);
4772 done:
4773 IDirect3D9_Release(d3d);
4774 DestroyWindow(window);
4777 static void texdepth_test(void)
4779 IDirect3DPixelShader9 *shader;
4780 IDirect3DDevice9 *device;
4781 IDirect3D9 *d3d;
4782 ULONG refcount;
4783 D3DCAPS9 caps;
4784 DWORD color;
4785 HWND window;
4786 HRESULT hr;
4788 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
4789 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
4790 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
4791 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
4792 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
4793 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
4794 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
4795 static const DWORD shader_code[] =
4797 0xffff0104, /* ps_1_4 */
4798 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4799 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4800 0x0000fffd, /* phase */
4801 0x00000057, 0x800f0005, /* texdepth r5 */
4802 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4803 0x0000ffff /* end */
4805 static const float vertex[] =
4807 -1.0f, -1.0f, 0.0f,
4808 -1.0f, 1.0f, 0.0f,
4809 1.0f, -1.0f, 1.0f,
4810 1.0f, 1.0f, 1.0f,
4813 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4814 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4815 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4816 ok(!!d3d, "Failed to create a D3D object.\n");
4817 if (!(device = create_device(d3d, window, window, TRUE)))
4819 skip("Failed to create a D3D device, skipping tests.\n");
4820 goto done;
4823 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4824 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4825 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4827 skip("No ps_1_1 support, skipping tests.\n");
4828 IDirect3DDevice9_Release(device);
4829 goto done;
4832 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4833 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4838 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4845 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4846 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4848 /* Fill the depth buffer with a gradient */
4849 hr = IDirect3DDevice9_BeginScene(device);
4850 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4852 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4853 hr = IDirect3DDevice9_EndScene(device);
4854 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4856 /* Now perform the actual tests. Same geometry, but with the shader */
4857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4858 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4860 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4861 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4864 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4865 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4866 hr = IDirect3DDevice9_BeginScene(device);
4867 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4868 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4869 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4870 hr = IDirect3DDevice9_EndScene(device);
4871 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4873 color = getPixelColor(device, 158, 240);
4874 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4875 color = getPixelColor(device, 162, 240);
4876 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4879 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4882 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4884 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4885 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4886 hr = IDirect3DDevice9_BeginScene(device);
4887 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4889 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4890 hr = IDirect3DDevice9_EndScene(device);
4891 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4893 color = getPixelColor(device, 318, 240);
4894 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4895 color = getPixelColor(device, 322, 240);
4896 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4898 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4899 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4901 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4902 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4904 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4905 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4906 hr = IDirect3DDevice9_BeginScene(device);
4907 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4908 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4909 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4910 hr = IDirect3DDevice9_EndScene(device);
4911 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4913 color = getPixelColor(device, 1, 240);
4914 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4916 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4917 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4919 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4920 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4922 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4923 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4924 hr = IDirect3DDevice9_BeginScene(device);
4925 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4927 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4928 hr = IDirect3DDevice9_EndScene(device);
4929 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4931 color = getPixelColor(device, 318, 240);
4932 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4933 color = getPixelColor(device, 322, 240);
4934 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4937 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4940 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4942 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4944 hr = IDirect3DDevice9_BeginScene(device);
4945 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4948 hr = IDirect3DDevice9_EndScene(device);
4949 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4951 color = getPixelColor(device, 1, 240);
4952 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4954 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4957 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4958 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4960 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4961 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4962 hr = IDirect3DDevice9_BeginScene(device);
4963 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4965 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4966 hr = IDirect3DDevice9_EndScene(device);
4967 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4969 color = getPixelColor(device, 638, 240);
4970 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4972 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4973 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4976 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4978 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4979 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4980 hr = IDirect3DDevice9_BeginScene(device);
4981 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4983 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4984 hr = IDirect3DDevice9_EndScene(device);
4985 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4987 color = getPixelColor(device, 638, 240);
4988 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4993 IDirect3DPixelShader9_Release(shader);
4994 refcount = IDirect3DDevice9_Release(device);
4995 ok(!refcount, "Device has %u references left.\n", refcount);
4996 done:
4997 IDirect3D9_Release(d3d);
4998 DestroyWindow(window);
5001 static void texkill_test(void)
5003 IDirect3DPixelShader9 *shader;
5004 IDirect3DDevice9 *device;
5005 IDirect3D9 *d3d;
5006 ULONG refcount;
5007 D3DCAPS9 caps;
5008 DWORD color;
5009 HWND window;
5010 HRESULT hr;
5012 static const float vertex[] =
5014 /* bottom top right left */
5015 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5016 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5017 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5018 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5020 static const DWORD shader_code_11[] =
5022 0xffff0101, /* ps_1_1 */
5023 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5024 0x00000041, 0xb00f0000, /* texkill t0 */
5025 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5026 0x0000ffff /* end */
5028 static const DWORD shader_code_20[] =
5030 0xffff0200, /* ps_2_0 */
5031 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5032 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5033 0x01000041, 0xb00f0000, /* texkill t0 */
5034 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5035 0x0000ffff /* end */
5038 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5039 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5040 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5041 ok(!!d3d, "Failed to create a D3D object.\n");
5042 if (!(device = create_device(d3d, window, window, TRUE)))
5044 skip("Failed to create a D3D device, skipping tests.\n");
5045 goto done;
5048 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5049 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5050 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5052 skip("No ps_1_1 support, skipping tests.\n");
5053 IDirect3DDevice9_Release(device);
5054 goto done;
5057 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5058 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5059 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5060 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5062 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5064 hr = IDirect3DDevice9_BeginScene(device);
5065 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5066 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5067 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5069 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5070 hr = IDirect3DDevice9_EndScene(device);
5071 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5073 color = getPixelColor(device, 63, 46);
5074 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5075 color = getPixelColor(device, 66, 46);
5076 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5077 color = getPixelColor(device, 63, 49);
5078 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5079 color = getPixelColor(device, 66, 49);
5080 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5082 color = getPixelColor(device, 578, 46);
5083 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5084 color = getPixelColor(device, 575, 46);
5085 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5086 color = getPixelColor(device, 578, 49);
5087 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5088 color = getPixelColor(device, 575, 49);
5089 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5091 color = getPixelColor(device, 63, 430);
5092 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5093 color = getPixelColor(device, 63, 433);
5094 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5095 color = getPixelColor(device, 66, 433);
5096 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5097 color = getPixelColor(device, 66, 430);
5098 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5100 color = getPixelColor(device, 578, 430);
5101 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5102 color = getPixelColor(device, 578, 433);
5103 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5104 color = getPixelColor(device, 575, 433);
5105 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5106 color = getPixelColor(device, 575, 430);
5107 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5109 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5110 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5112 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5113 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5114 IDirect3DPixelShader9_Release(shader);
5116 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5117 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5118 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5120 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5121 IDirect3DDevice9_Release(device);
5122 goto done;
5125 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5126 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5127 hr = IDirect3DDevice9_BeginScene(device);
5128 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5130 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5131 hr = IDirect3DDevice9_EndScene(device);
5132 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5134 color = getPixelColor(device, 63, 46);
5135 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5136 color = getPixelColor(device, 66, 46);
5137 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5138 color = getPixelColor(device, 63, 49);
5139 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5140 color = getPixelColor(device, 66, 49);
5141 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5143 color = getPixelColor(device, 578, 46);
5144 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5145 color = getPixelColor(device, 575, 46);
5146 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5147 color = getPixelColor(device, 578, 49);
5148 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5149 color = getPixelColor(device, 575, 49);
5150 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5152 color = getPixelColor(device, 63, 430);
5153 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5154 color = getPixelColor(device, 63, 433);
5155 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5156 color = getPixelColor(device, 66, 433);
5157 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5158 color = getPixelColor(device, 66, 430);
5159 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5161 color = getPixelColor(device, 578, 430);
5162 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5163 color = getPixelColor(device, 578, 433);
5164 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5165 color = getPixelColor(device, 575, 433);
5166 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5167 color = getPixelColor(device, 575, 430);
5168 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5170 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5171 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5173 IDirect3DPixelShader9_Release(shader);
5174 refcount = IDirect3DDevice9_Release(device);
5175 ok(!refcount, "Device has %u references left.\n", refcount);
5176 done:
5177 IDirect3D9_Release(d3d);
5178 DestroyWindow(window);
5181 static void x8l8v8u8_test(void)
5183 IDirect3DPixelShader9 *shader2;
5184 IDirect3DPixelShader9 *shader;
5185 IDirect3DTexture9 *texture;
5186 IDirect3DDevice9 *device;
5187 D3DLOCKED_RECT lr;
5188 IDirect3D9 *d3d;
5189 ULONG refcount;
5190 D3DCAPS9 caps;
5191 DWORD color;
5192 HWND window;
5193 HRESULT hr;
5195 static const DWORD shader_code[] =
5197 0xffff0101, /* ps_1_1 */
5198 0x00000042, 0xb00f0000, /* tex t0 */
5199 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5200 0x0000ffff /* end */
5202 static const DWORD shader_code2[] =
5204 0xffff0101, /* ps_1_1 */
5205 0x00000042, 0xb00f0000, /* tex t0 */
5206 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
5207 0x0000ffff /* end */
5209 static const float quad[] =
5211 -1.0f, -1.0f, 0.1f, 0.5f, 0.5f,
5212 -1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5213 1.0f, -1.0f, 0.1f, 0.5f, 0.5f,
5214 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5217 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5218 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5219 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5220 ok(!!d3d, "Failed to create a D3D object.\n");
5221 if (!(device = create_device(d3d, window, window, TRUE)))
5223 skip("Failed to create a D3D device, skipping tests.\n");
5224 goto done;
5227 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5228 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5229 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5231 skip("No ps_1_1 support, skipping tests.\n");
5232 IDirect3DDevice9_Release(device);
5233 goto done;
5235 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5236 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8)))
5238 skip("No D3DFMT_X8L8V8U8 support, skipping tests.\n");
5239 IDirect3DDevice9_Release(device);
5240 goto done;
5243 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
5244 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5246 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5247 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5248 memset(&lr, 0, sizeof(lr));
5249 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5250 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5251 *((DWORD *) lr.pBits) = 0x11ca3141;
5252 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5253 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5255 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5256 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5257 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5258 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5260 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5261 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5262 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5263 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5264 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5265 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5267 hr = IDirect3DDevice9_BeginScene(device);
5268 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5269 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5270 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5271 hr = IDirect3DDevice9_EndScene(device);
5272 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5274 color = getPixelColor(device, 578, 430);
5275 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5276 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5277 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5278 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5280 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5281 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5282 hr = IDirect3DDevice9_BeginScene(device);
5283 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5285 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5286 hr = IDirect3DDevice9_EndScene(device);
5287 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5289 color = getPixelColor(device, 578, 430);
5290 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5291 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5292 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5294 IDirect3DPixelShader9_Release(shader);
5295 IDirect3DPixelShader9_Release(shader2);
5296 IDirect3DTexture9_Release(texture);
5297 refcount = IDirect3DDevice9_Release(device);
5298 ok(!refcount, "Device has %u references left.\n", refcount);
5299 done:
5300 IDirect3D9_Release(d3d);
5301 DestroyWindow(window);
5304 static void autogen_mipmap_test(void)
5306 IDirect3DTexture9 *texture = NULL;
5307 IDirect3DSurface9 *surface;
5308 IDirect3DDevice9 *device;
5309 unsigned int x, y;
5310 D3DLOCKED_RECT lr;
5311 IDirect3D9 *d3d;
5312 D3DCOLOR color;
5313 ULONG refcount;
5314 HWND window;
5315 HRESULT hr;
5317 static const RECT r1 = {256, 256, 512, 512};
5318 static const RECT r2 = {512, 256, 768, 512};
5319 static const RECT r3 = {256, 512, 512, 768};
5320 static const RECT r4 = {512, 512, 768, 768};
5321 static const float quad[] =
5323 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5324 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5325 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5326 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5329 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5330 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5331 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5332 ok(!!d3d, "Failed to create a D3D object.\n");
5333 if (!(device = create_device(d3d, window, window, TRUE)))
5335 skip("Failed to create a D3D device, skipping tests.\n");
5336 goto done;
5339 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5340 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5342 skip("No autogenmipmap support.\n");
5343 IDirect3DDevice9_Release(device);
5344 goto done;
5347 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5350 /* Make the mipmap big, so that a smaller mipmap is used
5352 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5353 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5354 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5356 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5357 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5358 memset(&lr, 0, sizeof(lr));
5359 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5360 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5361 for(y = 0; y < 1024; y++) {
5362 for(x = 0; x < 1024; x++) {
5363 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5364 POINT pt;
5366 pt.x = x;
5367 pt.y = y;
5368 if(PtInRect(&r1, pt)) {
5369 *dst = 0xffff0000;
5370 } else if(PtInRect(&r2, pt)) {
5371 *dst = 0xff00ff00;
5372 } else if(PtInRect(&r3, pt)) {
5373 *dst = 0xff0000ff;
5374 } else if(PtInRect(&r4, pt)) {
5375 *dst = 0xff000000;
5376 } else {
5377 *dst = 0xffffffff;
5381 hr = IDirect3DSurface9_UnlockRect(surface);
5382 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5383 IDirect3DSurface9_Release(surface);
5385 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5386 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5387 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5388 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5390 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5392 hr = IDirect3DDevice9_BeginScene(device);
5393 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5395 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5397 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5398 hr = IDirect3DDevice9_EndScene(device);
5399 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5400 IDirect3DTexture9_Release(texture);
5402 color = getPixelColor(device, 200, 200);
5403 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5404 color = getPixelColor(device, 280, 200);
5405 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5406 color = getPixelColor(device, 360, 200);
5407 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5408 color = getPixelColor(device, 440, 200);
5409 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5410 color = getPixelColor(device, 200, 270);
5411 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5412 color = getPixelColor(device, 280, 270);
5413 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5414 color = getPixelColor(device, 360, 270);
5415 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5416 color = getPixelColor(device, 440, 270);
5417 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5418 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5419 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5421 refcount = IDirect3DDevice9_Release(device);
5422 ok(!refcount, "Device has %u references left.\n", refcount);
5423 done:
5424 IDirect3D9_Release(d3d);
5425 DestroyWindow(window);
5428 static void test_constant_clamp_vs(void)
5430 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5431 IDirect3DVertexDeclaration9 *decl;
5432 IDirect3DDevice9 *device;
5433 IDirect3D9 *d3d;
5434 D3DCOLOR color;
5435 ULONG refcount;
5436 D3DCAPS9 caps;
5437 HWND window;
5438 HRESULT hr;
5440 static const DWORD shader_code_11[] =
5442 0xfffe0101, /* vs_1_1 */
5443 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5444 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5445 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5446 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5447 0x0000ffff /* end */
5449 static const DWORD shader_code_11_2[] =
5451 0xfffe0101, /* vs_1_1 */
5452 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5453 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5454 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5455 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5456 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5457 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5458 0x0000ffff /* end */
5460 static const DWORD shader_code_20[] =
5462 0xfffe0200, /* vs_2_0 */
5463 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5464 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5465 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5466 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5467 0x0000ffff /* end */
5469 static const DWORD shader_code_20_2[] =
5471 0xfffe0200, /* vs_2_0 */
5472 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5473 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5474 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5475 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5476 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5477 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5478 0x0000ffff /* end */
5480 static const D3DVERTEXELEMENT9 decl_elements[] =
5482 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5483 D3DDECL_END()
5485 static const float quad1[] =
5487 -1.0f, -1.0f, 0.1f,
5488 -1.0f, 0.0f, 0.1f,
5489 0.0f, -1.0f, 0.1f,
5490 0.0f, 0.0f, 0.1f,
5492 static const float quad2[] =
5494 0.0f, -1.0f, 0.1f,
5495 0.0f, 0.0f, 0.1f,
5496 1.0f, -1.0f, 0.1f,
5497 1.0f, 0.0f, 0.1f,
5499 static const float quad3[] =
5501 0.0f, 0.0f, 0.1f,
5502 0.0f, 1.0f, 0.1f,
5503 1.0f, 0.0f, 0.1f,
5504 1.0f, 1.0f, 0.1f,
5506 static const float quad4[] =
5508 -1.0f, 0.0f, 0.1f,
5509 -1.0f, 1.0f, 0.1f,
5510 0.0f, 0.0f, 0.1f,
5511 0.0f, 1.0f, 0.1f,
5513 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5514 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5516 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5517 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5518 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5519 ok(!!d3d, "Failed to create a D3D object.\n");
5520 if (!(device = create_device(d3d, window, window, TRUE)))
5522 skip("Failed to create a D3D device, skipping tests.\n");
5523 goto done;
5526 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5527 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5528 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
5530 skip("No vs_1_1 support, skipping tests.\n");
5531 IDirect3DDevice9_Release(device);
5532 goto done;
5535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5536 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5538 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5539 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5540 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5541 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5542 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5543 if(FAILED(hr)) shader_20 = NULL;
5544 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5545 if(FAILED(hr)) shader_20_2 = NULL;
5546 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5547 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5549 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5550 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5551 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5552 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5553 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5554 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5556 hr = IDirect3DDevice9_BeginScene(device);
5557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5559 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5560 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5562 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5564 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5565 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5567 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5569 if (shader_20)
5571 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5572 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5574 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5577 if (shader_20_2)
5579 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5580 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5582 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5585 hr = IDirect3DDevice9_EndScene(device);
5586 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5588 color = getPixelColor(device, 160, 360);
5589 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5590 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5591 color = getPixelColor(device, 480, 360);
5592 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5593 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5594 if(shader_20) {
5595 color = getPixelColor(device, 480, 120);
5596 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5597 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5599 if(shader_20_2) {
5600 color = getPixelColor(device, 160, 120);
5601 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5602 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5604 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5605 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5607 IDirect3DVertexDeclaration9_Release(decl);
5608 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5609 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5610 IDirect3DVertexShader9_Release(shader_11_2);
5611 IDirect3DVertexShader9_Release(shader_11);
5612 refcount = IDirect3DDevice9_Release(device);
5613 ok(!refcount, "Device has %u references left.\n", refcount);
5614 done:
5615 IDirect3D9_Release(d3d);
5616 DestroyWindow(window);
5619 static void constant_clamp_ps_test(void)
5621 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5622 IDirect3DDevice9 *device;
5623 IDirect3D9 *d3d;
5624 ULONG refcount;
5625 D3DCAPS9 caps;
5626 DWORD color;
5627 HWND window;
5628 HRESULT hr;
5630 static const DWORD shader_code_11[] =
5632 0xffff0101, /* ps_1_1 */
5633 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5634 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5635 0x0000ffff /* end */
5637 static const DWORD shader_code_12[] =
5639 0xffff0102, /* ps_1_2 */
5640 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5641 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5642 0x0000ffff /* end */
5644 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
5645 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
5646 * unlikely that 1.3 shaders are different. During development of this
5647 * test, 1.3 shaders were verified too. */
5648 static const DWORD shader_code_14[] =
5650 0xffff0104, /* ps_1_4 */
5651 /* Try to make one constant local. It gets clamped too, although the
5652 * binary contains the bigger numbers. */
5653 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5654 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5655 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5656 0x0000ffff /* end */
5658 static const DWORD shader_code_20[] =
5660 0xffff0200, /* ps_2_0 */
5661 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5662 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5663 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5664 0x0000ffff /* end */
5666 static const float quad1[] =
5668 -1.0f, -1.0f, 0.1f,
5669 -1.0f, 0.0f, 0.1f,
5670 0.0f, -1.0f, 0.1f,
5671 0.0f, 0.0f, 0.1f,
5673 static const float quad2[] =
5675 0.0f, -1.0f, 0.1f,
5676 0.0f, 0.0f, 0.1f,
5677 1.0f, -1.0f, 0.1f,
5678 1.0f, 0.0f, 0.1f,
5680 static const float quad3[] =
5682 0.0f, 0.0f, 0.1f,
5683 0.0f, 1.0f, 0.1f,
5684 1.0f, 0.0f, 0.1f,
5685 1.0f, 1.0f, 0.1f,
5687 static const float quad4[] =
5689 -1.0f, 0.0f, 0.1f,
5690 -1.0f, 1.0f, 0.1f,
5691 0.0f, 0.0f, 0.1f,
5692 0.0f, 1.0f, 0.1f,
5694 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5695 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5697 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5698 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5699 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5700 ok(!!d3d, "Failed to create a D3D object.\n");
5701 if (!(device = create_device(d3d, window, window, TRUE)))
5703 skip("Failed to create a D3D device, skipping tests.\n");
5704 goto done;
5707 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5708 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5709 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5711 skip("No ps_1_4 support, skipping tests.\n");
5712 IDirect3DDevice9_Release(device);
5713 goto done;
5716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5717 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5719 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5721 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5722 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5723 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5724 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5725 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5726 if(FAILED(hr)) shader_20 = NULL;
5728 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5729 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5730 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5731 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5732 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5733 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5735 hr = IDirect3DDevice9_BeginScene(device);
5736 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5738 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5739 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5741 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5743 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5744 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5745 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5746 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5748 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5749 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5751 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5753 if (shader_20)
5755 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5756 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5757 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5758 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5761 hr = IDirect3DDevice9_EndScene(device);
5762 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5764 color = getPixelColor(device, 160, 360);
5765 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5766 "quad 1 has color %08x, expected 0x00808000\n", color);
5767 color = getPixelColor(device, 480, 360);
5768 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5769 "quad 2 has color %08x, expected 0x00808000\n", color);
5770 color = getPixelColor(device, 480, 120);
5771 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5772 "quad 3 has color %08x, expected 0x00808000\n", color);
5773 if(shader_20) {
5774 color = getPixelColor(device, 160, 120);
5775 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5776 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5781 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5782 IDirect3DPixelShader9_Release(shader_14);
5783 IDirect3DPixelShader9_Release(shader_12);
5784 IDirect3DPixelShader9_Release(shader_11);
5785 refcount = IDirect3DDevice9_Release(device);
5786 ok(!refcount, "Device has %u references left.\n", refcount);
5787 done:
5788 IDirect3D9_Release(d3d);
5789 DestroyWindow(window);
5792 static void dp2add_ps_test(void)
5794 IDirect3DPixelShader9 *shader_dp2add_sat;
5795 IDirect3DPixelShader9 *shader_dp2add;
5796 IDirect3DDevice9 *device;
5797 IDirect3D9 *d3d;
5798 ULONG refcount;
5799 D3DCAPS9 caps;
5800 DWORD color;
5801 HWND window;
5802 HRESULT hr;
5804 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5805 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5806 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5807 * r0 first.
5808 * The result here for the r,g,b components should be roughly 0.5:
5809 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5810 static const DWORD shader_code_dp2add[] = {
5811 0xffff0200, /* ps_2_0 */
5812 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5814 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5815 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5817 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5818 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5819 0x0000ffff /* end */
5822 /* Test the _sat modifier, too. Result here should be:
5823 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5824 * _SAT: ==> 1.0
5825 * ADD: (1.0 + -0.5) = 0.5
5827 static const DWORD shader_code_dp2add_sat[] = {
5828 0xffff0200, /* ps_2_0 */
5829 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5831 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5832 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5833 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5835 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5836 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5837 0x0000ffff /* end */
5839 static const float quad[] =
5841 -1.0f, -1.0f, 0.1f,
5842 -1.0f, 1.0f, 0.1f,
5843 1.0f, -1.0f, 0.1f,
5844 1.0f, 1.0f, 0.1f,
5847 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5848 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5849 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5850 ok(!!d3d, "Failed to create a D3D object.\n");
5851 if (!(device = create_device(d3d, window, window, TRUE)))
5853 skip("Failed to create a D3D device, skipping tests.\n");
5854 goto done;
5857 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5858 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5859 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
5861 skip("No ps_2_0 support, skipping tests.\n");
5862 IDirect3DDevice9_Release(device);
5863 goto done;
5866 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
5867 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5869 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5870 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5872 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5873 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5875 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5876 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5878 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5879 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5880 hr = IDirect3DDevice9_BeginScene(device);
5881 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5883 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
5884 hr = IDirect3DDevice9_EndScene(device);
5885 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5887 color = getPixelColor(device, 360, 240);
5888 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
5890 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5891 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
5892 IDirect3DPixelShader9_Release(shader_dp2add);
5894 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5895 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5896 hr = IDirect3DDevice9_BeginScene(device);
5897 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5898 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5899 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
5900 hr = IDirect3DDevice9_EndScene(device);
5901 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5903 color = getPixelColor(device, 360, 240);
5904 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
5906 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5907 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
5908 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5910 refcount = IDirect3DDevice9_Release(device);
5911 ok(!refcount, "Device has %u references left.\n", refcount);
5912 done:
5913 IDirect3D9_Release(d3d);
5914 DestroyWindow(window);
5917 static void cnd_test(void)
5919 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
5920 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5921 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5922 IDirect3DDevice9 *device;
5923 IDirect3D9 *d3d;
5924 ULONG refcount;
5925 D3DCAPS9 caps;
5926 HWND window;
5927 DWORD color;
5928 HRESULT hr;
5930 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
5931 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
5932 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
5933 * in 1.x pixel shaders. */
5934 static const DWORD shader_code_11[] =
5936 0xffff0101, /* ps_1_1 */
5937 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5938 0x00000040, 0xb00f0000, /* texcoord t0 */
5939 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5940 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5941 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5942 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5943 0x0000ffff /* end */
5945 static const DWORD shader_code_12[] =
5947 0xffff0102, /* ps_1_2 */
5948 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5949 0x00000040, 0xb00f0000, /* texcoord t0 */
5950 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5951 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5952 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5953 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5954 0x0000ffff /* end */
5956 static const DWORD shader_code_13[] =
5958 0xffff0103, /* ps_1_3 */
5959 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5960 0x00000040, 0xb00f0000, /* texcoord t0 */
5961 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5962 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5963 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5964 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5965 0x0000ffff /* end */
5967 static const DWORD shader_code_14[] =
5969 0xffff0104, /* ps_1_3 */
5970 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5971 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5972 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5973 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5974 0x0000ffff /* end */
5977 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5978 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5979 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5980 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5981 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5982 * well enough.
5984 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5985 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5986 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5987 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5989 static const DWORD shader_code_11_coissue[] =
5991 0xffff0101, /* ps_1_1 */
5992 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5993 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5994 0x00000040, 0xb00f0000, /* texcoord t0 */
5995 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5996 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5997 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5998 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
5999 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6000 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6001 0x0000ffff /* end */
6003 static const DWORD shader_code_11_coissue_2[] =
6005 0xffff0101, /* ps_1_1 */
6006 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6007 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6008 0x00000040, 0xb00f0000, /* texcoord t0 */
6009 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6010 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6011 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6012 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6013 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6014 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6015 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6016 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6017 0x0000ffff /* end */
6019 static const DWORD shader_code_12_coissue[] =
6021 0xffff0102, /* ps_1_2 */
6022 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6023 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6024 0x00000040, 0xb00f0000, /* texcoord t0 */
6025 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6026 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6027 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6028 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6029 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6030 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6031 0x0000ffff /* end */
6033 static const DWORD shader_code_12_coissue_2[] =
6035 0xffff0102, /* ps_1_2 */
6036 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6037 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6038 0x00000040, 0xb00f0000, /* texcoord t0 */
6039 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6040 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6041 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6042 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6043 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6044 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6045 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6046 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6047 0x0000ffff /* end */
6049 static const DWORD shader_code_13_coissue[] =
6051 0xffff0103, /* ps_1_3 */
6052 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6053 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6054 0x00000040, 0xb00f0000, /* texcoord t0 */
6055 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6056 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6057 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6058 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6059 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6060 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6061 0x0000ffff /* end */
6063 static const DWORD shader_code_13_coissue_2[] =
6065 0xffff0103, /* ps_1_3 */
6066 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6067 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6068 0x00000040, 0xb00f0000, /* texcoord t0 */
6069 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6070 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6071 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6072 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6073 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6074 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6075 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6076 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6077 0x0000ffff /* end */
6079 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6080 * texcrd result to cnd, it will compare against 0.5. */
6081 static const DWORD shader_code_14_coissue[] =
6083 0xffff0104, /* ps_1_4 */
6084 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6085 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6086 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6087 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6088 0x0000ffff /* end */
6090 static const DWORD shader_code_14_coissue_2[] =
6092 0xffff0104, /* ps_1_4 */
6093 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6094 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6095 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6096 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6097 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6098 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6099 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6100 0x0000ffff /* end */
6102 static const float quad1[] =
6104 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6105 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6106 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6107 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6109 static const float quad2[] =
6111 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6112 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6113 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6114 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6116 static const float quad3[] =
6118 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6119 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6120 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6121 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6123 static const float quad4[] =
6125 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6126 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6127 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6128 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6130 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6131 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6132 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6133 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6135 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6136 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6137 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6138 ok(!!d3d, "Failed to create a D3D object.\n");
6139 if (!(device = create_device(d3d, window, window, TRUE)))
6141 skip("Failed to create a D3D device, skipping tests.\n");
6142 goto done;
6145 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6146 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6147 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6149 skip("No ps_1_4 support, skipping tests.\n");
6150 IDirect3DDevice9_Release(device);
6151 goto done;
6154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6157 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6158 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6159 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6160 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6161 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6162 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6163 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6164 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6165 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6166 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6167 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6168 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6169 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6170 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6171 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6173 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6175 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6176 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6177 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6178 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6179 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6182 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6183 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6184 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6185 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6186 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6187 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6189 hr = IDirect3DDevice9_BeginScene(device);
6190 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6192 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6193 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6194 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6195 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6197 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6198 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6200 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6202 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6203 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6205 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6207 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6208 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6210 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6212 hr = IDirect3DDevice9_EndScene(device);
6213 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6215 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6216 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6218 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6219 color = getPixelColor(device, 158, 118);
6220 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6221 color = getPixelColor(device, 162, 118);
6222 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6223 color = getPixelColor(device, 158, 122);
6224 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6225 color = getPixelColor(device, 162, 122);
6226 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6228 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6229 color = getPixelColor(device, 158, 358);
6230 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6231 color = getPixelColor(device, 162, 358);
6232 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6233 color = getPixelColor(device, 158, 362);
6234 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6235 color = getPixelColor(device, 162, 362);
6236 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6238 /* 1.2 shader */
6239 color = getPixelColor(device, 478, 358);
6240 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6241 color = getPixelColor(device, 482, 358);
6242 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6243 color = getPixelColor(device, 478, 362);
6244 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6245 color = getPixelColor(device, 482, 362);
6246 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6248 /* 1.3 shader */
6249 color = getPixelColor(device, 478, 118);
6250 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6251 color = getPixelColor(device, 482, 118);
6252 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6253 color = getPixelColor(device, 478, 122);
6254 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6255 color = getPixelColor(device, 482, 122);
6256 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6258 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6259 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6262 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6263 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6264 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6265 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6266 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6268 hr = IDirect3DDevice9_BeginScene(device);
6269 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6271 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6272 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6274 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6276 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6277 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6279 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6281 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6282 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6284 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6286 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6287 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6289 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6291 hr = IDirect3DDevice9_EndScene(device);
6292 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6294 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6295 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6297 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6298 * that we swapped the values in c1 and c2 to make the other tests return some color
6300 color = getPixelColor(device, 158, 118);
6301 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6302 color = getPixelColor(device, 162, 118);
6303 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6304 color = getPixelColor(device, 158, 122);
6305 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6306 color = getPixelColor(device, 162, 122);
6307 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6309 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6310 * (The Win7 nvidia driver always selects c2)
6312 color = getPixelColor(device, 158, 358);
6313 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6314 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6315 color = getPixelColor(device, 162, 358);
6316 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6317 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6318 color = getPixelColor(device, 158, 362);
6319 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6320 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6321 color = getPixelColor(device, 162, 362);
6322 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6323 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6325 /* 1.2 shader */
6326 color = getPixelColor(device, 478, 358);
6327 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6328 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6329 color = getPixelColor(device, 482, 358);
6330 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6331 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6332 color = getPixelColor(device, 478, 362);
6333 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6334 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6335 color = getPixelColor(device, 482, 362);
6336 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6337 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6339 /* 1.3 shader */
6340 color = getPixelColor(device, 478, 118);
6341 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6342 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6343 color = getPixelColor(device, 482, 118);
6344 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6345 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6346 color = getPixelColor(device, 478, 122);
6347 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6348 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6349 color = getPixelColor(device, 482, 122);
6350 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6351 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6353 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6356 /* Retest with the coissue flag on the alpha instruction instead. This
6357 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6358 * the same as coissue on .rgb. */
6359 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6360 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6362 hr = IDirect3DDevice9_BeginScene(device);
6363 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6365 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6366 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6368 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6370 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6371 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6373 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6375 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6376 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6378 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6380 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6381 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6383 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6385 hr = IDirect3DDevice9_EndScene(device);
6386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6388 /* 1.4 shader */
6389 color = getPixelColor(device, 158, 118);
6390 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6391 color = getPixelColor(device, 162, 118);
6392 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6393 color = getPixelColor(device, 158, 122);
6394 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6395 color = getPixelColor(device, 162, 122);
6396 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6398 /* 1.1 shader */
6399 color = getPixelColor(device, 238, 358);
6400 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6401 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6402 color = getPixelColor(device, 242, 358);
6403 ok(color_match(color, 0x00000000, 1),
6404 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6405 color = getPixelColor(device, 238, 362);
6406 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6407 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6408 color = getPixelColor(device, 242, 362);
6409 ok(color_match(color, 0x00000000, 1),
6410 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6412 /* 1.2 shader */
6413 color = getPixelColor(device, 558, 358);
6414 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6415 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6416 color = getPixelColor(device, 562, 358);
6417 ok(color_match(color, 0x00000000, 1),
6418 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6419 color = getPixelColor(device, 558, 362);
6420 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6421 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6422 color = getPixelColor(device, 562, 362);
6423 ok(color_match(color, 0x00000000, 1),
6424 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6426 /* 1.3 shader */
6427 color = getPixelColor(device, 558, 118);
6428 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6429 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6430 color = getPixelColor(device, 562, 118);
6431 ok(color_match(color, 0x00000000, 1),
6432 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6433 color = getPixelColor(device, 558, 122);
6434 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6435 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6436 color = getPixelColor(device, 562, 122);
6437 ok(color_match(color, 0x00000000, 1),
6438 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6440 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6441 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6443 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6444 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6445 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6446 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6447 IDirect3DPixelShader9_Release(shader_14_coissue);
6448 IDirect3DPixelShader9_Release(shader_13_coissue);
6449 IDirect3DPixelShader9_Release(shader_12_coissue);
6450 IDirect3DPixelShader9_Release(shader_11_coissue);
6451 IDirect3DPixelShader9_Release(shader_14);
6452 IDirect3DPixelShader9_Release(shader_13);
6453 IDirect3DPixelShader9_Release(shader_12);
6454 IDirect3DPixelShader9_Release(shader_11);
6455 refcount = IDirect3DDevice9_Release(device);
6456 ok(!refcount, "Device has %u references left.\n", refcount);
6457 done:
6458 IDirect3D9_Release(d3d);
6459 DestroyWindow(window);
6462 static void nested_loop_test(void)
6464 IDirect3DVertexShader9 *vshader;
6465 IDirect3DPixelShader9 *shader;
6466 IDirect3DDevice9 *device;
6467 IDirect3D9 *d3d;
6468 ULONG refcount;
6469 D3DCAPS9 caps;
6470 DWORD color;
6471 HWND window;
6472 HRESULT hr;
6474 static const DWORD shader_code[] =
6476 0xffff0300, /* ps_3_0 */
6477 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6478 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6479 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
6480 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6481 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6482 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6483 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6484 0x0000001d, /* endloop */
6485 0x0000001d, /* endloop */
6486 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6487 0x0000ffff /* end */
6489 static const DWORD vshader_code[] =
6491 0xfffe0300, /* vs_3_0 */
6492 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6493 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6494 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6495 0x0000ffff /* end */
6497 static const float quad[] =
6499 -1.0f, -1.0f, 0.1f,
6500 -1.0f, 1.0f, 0.1f,
6501 1.0f, -1.0f, 0.1f,
6502 1.0f, 1.0f, 0.1f,
6505 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6506 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6507 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6508 ok(!!d3d, "Failed to create a D3D object.\n");
6509 if (!(device = create_device(d3d, window, window, TRUE)))
6511 skip("Failed to create a D3D device, skipping tests.\n");
6512 goto done;
6515 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6516 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6517 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6519 skip("No shader model 3 support, skipping tests.\n");
6520 IDirect3DDevice9_Release(device);
6521 goto done;
6524 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6525 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6526 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6527 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6528 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6529 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6530 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6531 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6533 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
6535 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6537 hr = IDirect3DDevice9_BeginScene(device);
6538 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6540 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6541 hr = IDirect3DDevice9_EndScene(device);
6542 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6544 color = getPixelColor(device, 360, 240);
6545 ok(color_match(color, 0x00800000, 1),
6546 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
6548 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6549 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6551 IDirect3DPixelShader9_Release(shader);
6552 IDirect3DVertexShader9_Release(vshader);
6553 refcount = IDirect3DDevice9_Release(device);
6554 ok(!refcount, "Device has %u references left.\n", refcount);
6555 done:
6556 IDirect3D9_Release(d3d);
6557 DestroyWindow(window);
6560 static void pretransformed_varying_test(void)
6562 /* dcl_position: fails to compile */
6563 static const DWORD blendweight_code[] =
6565 0xffff0300, /* ps_3_0 */
6566 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6567 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6568 0x0000ffff /* end */
6570 static const DWORD blendindices_code[] =
6572 0xffff0300, /* ps_3_0 */
6573 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6574 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6575 0x0000ffff /* end */
6577 static const DWORD normal_code[] =
6579 0xffff0300, /* ps_3_0 */
6580 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6581 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6582 0x0000ffff /* end */
6584 /* psize: fails? */
6585 static const DWORD texcoord0_code[] =
6587 0xffff0300, /* ps_3_0 */
6588 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6589 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6590 0x0000ffff /* end */
6592 static const DWORD tangent_code[] =
6594 0xffff0300, /* ps_3_0 */
6595 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6596 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6597 0x0000ffff /* end */
6599 static const DWORD binormal_code[] =
6601 0xffff0300, /* ps_3_0 */
6602 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6603 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6604 0x0000ffff /* end */
6606 /* tessfactor: fails */
6607 /* positiont: fails */
6608 static const DWORD color_code[] =
6610 0xffff0300, /* ps_3_0 */
6611 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6612 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6613 0x0000ffff /* end */
6615 static const DWORD fog_code[] =
6617 0xffff0300, /* ps_3_0 */
6618 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
6619 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6620 0x0000ffff /* end */
6622 static const DWORD depth_code[] =
6624 0xffff0300, /* ps_3_0 */
6625 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
6626 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6627 0x0000ffff /* end */
6629 static const DWORD specular_code[] =
6631 0xffff0300, /* ps_3_0 */
6632 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
6633 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6634 0x0000ffff /* end */
6636 /* sample: fails */
6638 static const struct
6640 const char *name;
6641 const DWORD *shader_code;
6642 DWORD color;
6643 BOOL todo;
6645 tests[] =
6647 {"blendweight", blendweight_code, 0x00191919, TRUE },
6648 {"blendindices", blendindices_code, 0x00333333, TRUE },
6649 {"normal", normal_code, 0x004c4c4c, TRUE },
6650 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
6651 {"tangent", tangent_code, 0x00999999, TRUE },
6652 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
6653 {"color", color_code, 0x00e6e6e6, FALSE},
6654 {"fog", fog_code, 0x00666666, TRUE },
6655 {"depth", depth_code, 0x00cccccc, TRUE },
6656 {"specular", specular_code, 0x004488ff, FALSE},
6658 /* Declare a monster vertex type :-) */
6659 static const D3DVERTEXELEMENT9 decl_elements[] = {
6660 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6661 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
6662 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
6663 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
6664 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
6665 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6666 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
6667 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
6668 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
6669 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6670 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
6671 D3DDECL_END()
6674 static const struct
6676 float pos_x, pos_y, pos_z, rhw;
6677 float weight_1, weight_2, weight_3, weight_4;
6678 float index_1, index_2, index_3, index_4;
6679 float normal_1, normal_2, normal_3, normal_4;
6680 float fog_1, fog_2, fog_3, fog_4;
6681 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
6682 float tangent_1, tangent_2, tangent_3, tangent_4;
6683 float binormal_1, binormal_2, binormal_3, binormal_4;
6684 float depth_1, depth_2, depth_3, depth_4;
6685 D3DCOLOR diffuse;
6686 D3DCOLOR specular;
6688 data[] =
6691 0.0f, 0.0f, 0.1f, 1.0f,
6692 0.1f, 0.1f, 0.1f, 0.1f,
6693 0.2f, 0.2f, 0.2f, 0.2f,
6694 0.3f, 0.3f, 0.3f, 0.3f,
6695 0.4f, 0.4f, 0.4f, 0.4f,
6696 0.5f, 0.55f, 0.55f, 0.55f,
6697 0.6f, 0.6f, 0.6f, 0.7f,
6698 0.7f, 0.7f, 0.7f, 0.6f,
6699 0.8f, 0.8f, 0.8f, 0.8f,
6700 0xe6e6e6e6, /* 0.9 * 256 */
6701 0x224488ff, /* Nothing special */
6704 640.0f, 0.0f, 0.1f, 1.0f,
6705 0.1f, 0.1f, 0.1f, 0.1f,
6706 0.2f, 0.2f, 0.2f, 0.2f,
6707 0.3f, 0.3f, 0.3f, 0.3f,
6708 0.4f, 0.4f, 0.4f, 0.4f,
6709 0.5f, 0.55f, 0.55f, 0.55f,
6710 0.6f, 0.6f, 0.6f, 0.7f,
6711 0.7f, 0.7f, 0.7f, 0.6f,
6712 0.8f, 0.8f, 0.8f, 0.8f,
6713 0xe6e6e6e6, /* 0.9 * 256 */
6714 0x224488ff, /* Nothing special */
6717 0.0f, 480.0f, 0.1f, 1.0f,
6718 0.1f, 0.1f, 0.1f, 0.1f,
6719 0.2f, 0.2f, 0.2f, 0.2f,
6720 0.3f, 0.3f, 0.3f, 0.3f,
6721 0.4f, 0.4f, 0.4f, 0.4f,
6722 0.5f, 0.55f, 0.55f, 0.55f,
6723 0.6f, 0.6f, 0.6f, 0.7f,
6724 0.7f, 0.7f, 0.7f, 0.6f,
6725 0.8f, 0.8f, 0.8f, 0.8f,
6726 0xe6e6e6e6, /* 0.9 * 256 */
6727 0x224488ff, /* Nothing special */
6730 640.0f, 480.0f, 0.1f, 1.0f,
6731 0.1f, 0.1f, 0.1f, 0.1f,
6732 0.2f, 0.2f, 0.2f, 0.2f,
6733 0.3f, 0.3f, 0.3f, 0.3f,
6734 0.4f, 0.4f, 0.4f, 0.4f,
6735 0.5f, 0.55f, 0.55f, 0.55f,
6736 0.6f, 0.6f, 0.6f, 0.7f,
6737 0.7f, 0.7f, 0.7f, 0.6f,
6738 0.8f, 0.8f, 0.8f, 0.8f,
6739 0xe6e6e6e6, /* 0.9 * 256 */
6740 0x224488ff, /* Nothing special */
6743 IDirect3DVertexDeclaration9 *decl;
6744 IDirect3DDevice9 *device;
6745 IDirect3D9 *d3d;
6746 unsigned int i;
6747 ULONG refcount;
6748 D3DCAPS9 caps;
6749 DWORD color;
6750 HWND window;
6751 HRESULT hr;
6753 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6754 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6755 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6756 ok(!!d3d, "Failed to create a D3D object.\n");
6757 if (!(device = create_device(d3d, window, window, TRUE)))
6759 skip("Failed to create a D3D device, skipping tests.\n");
6760 goto done;
6763 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6764 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6765 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6767 skip("No shader model 3 support, skipping tests.\n");
6768 IDirect3DDevice9_Release(device);
6769 goto done;
6772 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6773 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6774 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6775 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6777 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6779 IDirect3DPixelShader9 *shader;
6781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
6782 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6784 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
6785 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
6787 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6790 hr = IDirect3DDevice9_BeginScene(device);
6791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
6793 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6794 hr = IDirect3DDevice9_EndScene(device);
6795 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6797 /* This isn't a weekend's job to fix, ignore the problem for now.
6798 * Needs a replacement pipeline. */
6799 color = getPixelColor(device, 360, 240);
6800 if (tests[i].todo)
6801 todo_wine ok(color_match(color, tests[i].color, 1)
6802 || broken(color_match(color, 0x00000000, 1)
6803 && tests[i].shader_code == blendindices_code),
6804 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
6805 tests[i].name, color, tests[i].color);
6806 else
6807 ok(color_match(color, tests[i].color, 1),
6808 "Test %s returned color 0x%08x, expected 0x%08x.\n",
6809 tests[i].name, color, tests[i].color);
6811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6812 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6814 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6815 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
6816 IDirect3DPixelShader9_Release(shader);
6819 IDirect3DVertexDeclaration9_Release(decl);
6820 refcount = IDirect3DDevice9_Release(device);
6821 ok(!refcount, "Device has %u references left.\n", refcount);
6822 done:
6823 IDirect3D9_Release(d3d);
6824 DestroyWindow(window);
6827 static void test_compare_instructions(void)
6829 IDirect3DVertexShader9 *shader_slt_scalar;
6830 IDirect3DVertexShader9 *shader_sge_scalar;
6831 IDirect3DVertexShader9 *shader_slt_vec;
6832 IDirect3DVertexShader9 *shader_sge_vec;
6833 IDirect3DDevice9 *device;
6834 IDirect3D9 *d3d;
6835 D3DCOLOR color;
6836 ULONG refcount;
6837 D3DCAPS9 caps;
6838 HWND window;
6839 HRESULT hr;
6841 static const DWORD shader_sge_vec_code[] =
6843 0xfffe0101, /* vs_1_1 */
6844 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6845 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6846 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6847 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6848 0x0000ffff /* end */
6850 static const DWORD shader_slt_vec_code[] =
6852 0xfffe0101, /* vs_1_1 */
6853 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6854 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6855 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6856 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6857 0x0000ffff /* end */
6859 static const DWORD shader_sge_scalar_code[] =
6861 0xfffe0101, /* vs_1_1 */
6862 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6863 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6864 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6865 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6866 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6867 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6868 0x0000ffff /* end */
6870 static const DWORD shader_slt_scalar_code[] =
6872 0xfffe0101, /* vs_1_1 */
6873 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6874 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6875 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6876 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6877 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6878 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6879 0x0000ffff /* end */
6881 static const float quad1[] =
6883 -1.0f, -1.0f, 0.1f,
6884 -1.0f, 0.0f, 0.1f,
6885 0.0f, -1.0f, 0.1f,
6886 0.0f, 0.0f, 0.1f,
6888 static const float quad2[] =
6890 0.0f, -1.0f, 0.1f,
6891 0.0f, 0.0f, 0.1f,
6892 1.0f, -1.0f, 0.1f,
6893 1.0f, 0.0f, 0.1f,
6895 static const float quad3[] =
6897 -1.0f, 0.0f, 0.1f,
6898 -1.0f, 1.0f, 0.1f,
6899 0.0f, 0.0f, 0.1f,
6900 0.0f, 1.0f, 0.1f,
6902 static const float quad4[] =
6904 0.0f, 0.0f, 0.1f,
6905 0.0f, 1.0f, 0.1f,
6906 1.0f, 0.0f, 0.1f,
6907 1.0f, 1.0f, 0.1f,
6909 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
6910 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
6912 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6913 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6914 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6915 ok(!!d3d, "Failed to create a D3D object.\n");
6916 if (!(device = create_device(d3d, window, window, TRUE)))
6918 skip("Failed to create a D3D device, skipping tests.\n");
6919 goto done;
6922 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6923 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6924 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6926 skip("No vs_1_1 support, skipping tests.\n");
6927 IDirect3DDevice9_Release(device);
6928 goto done;
6931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
6932 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6934 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6935 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6936 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6937 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6938 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6939 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6940 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6941 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6942 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6943 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6944 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6945 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6946 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6947 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6949 hr = IDirect3DDevice9_BeginScene(device);
6950 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6952 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6953 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6955 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6957 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6958 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6960 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6962 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6963 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6965 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6967 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6968 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
6970 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6971 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6973 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6975 hr = IDirect3DDevice9_EndScene(device);
6976 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6978 color = getPixelColor(device, 160, 360);
6979 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
6980 color = getPixelColor(device, 480, 360);
6981 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
6982 color = getPixelColor(device, 160, 120);
6983 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
6984 color = getPixelColor(device, 480, 160);
6985 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6987 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6988 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6990 IDirect3DVertexShader9_Release(shader_sge_vec);
6991 IDirect3DVertexShader9_Release(shader_slt_vec);
6992 IDirect3DVertexShader9_Release(shader_sge_scalar);
6993 IDirect3DVertexShader9_Release(shader_slt_scalar);
6994 refcount = IDirect3DDevice9_Release(device);
6995 ok(!refcount, "Device has %u references left.\n", refcount);
6996 done:
6997 IDirect3D9_Release(d3d);
6998 DestroyWindow(window);
7001 static void test_vshader_input(void)
7003 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7004 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7005 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7006 D3DADAPTER_IDENTIFIER9 identifier;
7007 IDirect3DPixelShader9 *ps;
7008 IDirect3DDevice9 *device;
7009 IDirect3D9 *d3d;
7010 ULONG refcount;
7011 unsigned int i;
7012 D3DCAPS9 caps;
7013 DWORD color;
7014 HWND window;
7015 HRESULT hr;
7016 BOOL warp;
7018 static const DWORD swapped_shader_code_3[] =
7020 0xfffe0300, /* vs_3_0 */
7021 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7022 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7023 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7024 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7025 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7026 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7027 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7028 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7029 0x0000ffff /* end */
7031 static const DWORD swapped_shader_code_1[] =
7033 0xfffe0101, /* vs_1_1 */
7034 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7035 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7036 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7037 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7038 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7039 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7040 0x0000ffff /* end */
7042 static const DWORD swapped_shader_code_2[] =
7044 0xfffe0200, /* vs_2_0 */
7045 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7046 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7047 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7048 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7049 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7050 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7051 0x0000ffff /* end */
7053 static const DWORD texcoord_color_shader_code_3[] =
7055 0xfffe0300, /* vs_3_0 */
7056 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7057 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7058 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7059 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7060 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7061 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7062 0x0000ffff /* end */
7064 static const DWORD texcoord_color_shader_code_2[] =
7066 0xfffe0200, /* vs_2_0 */
7067 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7068 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7069 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7070 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7071 0x0000ffff /* end */
7073 static const DWORD texcoord_color_shader_code_1[] =
7075 0xfffe0101, /* vs_1_1 */
7076 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7077 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7078 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7079 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7080 0x0000ffff /* end */
7082 static const DWORD color_color_shader_code_3[] =
7084 0xfffe0300, /* vs_3_0 */
7085 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7086 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7087 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7088 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7089 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7090 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7091 0x0000ffff /* end */
7093 static const DWORD color_color_shader_code_2[] =
7095 0xfffe0200, /* vs_2_0 */
7096 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7097 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7098 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7099 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7100 0x0000ffff /* end */
7102 static const DWORD color_color_shader_code_1[] =
7104 0xfffe0101, /* vs_1_1 */
7105 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7106 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7107 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7108 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7109 0x0000ffff /* end */
7111 static const DWORD ps3_code[] =
7113 0xffff0300, /* ps_3_0 */
7114 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7115 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7116 0x0000ffff /* end */
7118 static const float quad1[] =
7120 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7121 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7122 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7123 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7125 static const float quad2[] =
7127 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7128 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7129 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7130 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7132 static const float quad3[] =
7134 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7135 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7136 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7137 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7139 static const float quad4[] =
7141 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7142 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7143 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7144 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7146 static const float quad1_modified[] =
7148 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7149 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7150 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7151 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7153 static const float quad2_modified[] =
7155 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7156 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7157 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7158 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7160 static const struct
7162 struct vec3 position;
7163 DWORD diffuse;
7165 quad1_color[] =
7167 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7168 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7169 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7170 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7172 quad2_color[] =
7174 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7175 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7176 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7177 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7179 quad3_color[] =
7181 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7182 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7183 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7184 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7186 static const float quad4_color[] =
7188 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7189 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7190 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7191 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7193 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7195 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7196 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7197 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7198 D3DDECL_END()
7200 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7202 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7203 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7204 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7205 D3DDECL_END()
7207 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7209 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7210 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7211 D3DDECL_END()
7213 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7215 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7216 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7217 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7218 D3DDECL_END()
7220 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7222 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7223 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7224 D3DDECL_END()
7226 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7228 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7229 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7230 D3DDECL_END()
7232 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7234 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7235 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7236 D3DDECL_END()
7238 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7240 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7241 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7242 D3DDECL_END()
7244 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7245 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7247 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7248 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7249 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7250 ok(!!d3d, "Failed to create a D3D object.\n");
7251 if (!(device = create_device(d3d, window, window, TRUE)))
7253 skip("Failed to create a D3D device, skipping tests.\n");
7254 goto done;
7257 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7258 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7259 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7261 skip("No vs_3_0 support, skipping tests.\n");
7262 IDirect3DDevice9_Release(device);
7263 goto done;
7266 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7267 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7268 warp = !strcmp(identifier.Description, "Microsoft Basic Render Driver");
7270 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7271 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7272 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7273 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7274 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7275 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7276 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7277 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7279 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7280 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7281 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7282 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7283 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7284 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7285 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7286 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7288 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7289 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7291 for (i = 1; i <= 3; ++i)
7293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7294 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7295 if(i == 3) {
7296 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7297 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7298 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7299 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7300 } else if(i == 2){
7301 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7302 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7303 } else if(i == 1) {
7304 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7305 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7308 hr = IDirect3DDevice9_BeginScene(device);
7309 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7311 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7312 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7314 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7315 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7317 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7319 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7320 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7322 if (i == 3 || i == 2)
7323 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7324 else if (i == 1)
7325 /* Succeeds or fails, depending on SW or HW vertex processing. */
7326 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7328 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7329 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7330 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7331 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7333 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7334 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7336 if (i == 3 || i == 2)
7337 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7338 else if (i == 1)
7339 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7341 hr = IDirect3DDevice9_EndScene(device);
7342 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7344 if(i == 3 || i == 2) {
7345 color = getPixelColor(device, 160, 360);
7346 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7347 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7349 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7350 color = getPixelColor(device, 480, 360);
7351 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7352 * mostly random data as input. */
7353 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7354 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7355 color = getPixelColor(device, 160, 120);
7356 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7357 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7358 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7360 color = getPixelColor(device, 480, 160);
7361 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7362 } else if(i == 1) {
7363 color = getPixelColor(device, 160, 360);
7364 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7365 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7366 color = getPixelColor(device, 480, 360);
7367 /* Accept the clear color as well in this case, since SW VP
7368 * returns an error. On the Windows 8 testbot (WARP) the draw
7369 * succeeds, but uses mostly random data as input. */
7370 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7371 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7372 color = getPixelColor(device, 160, 120);
7373 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7374 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7375 color = getPixelColor(device, 480, 160);
7376 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7379 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7380 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7383 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7385 /* Now find out if the whole streams are re-read, or just the last
7386 * active value for the vertices is used. */
7387 hr = IDirect3DDevice9_BeginScene(device);
7388 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7390 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7391 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7393 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7394 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7396 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7398 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7399 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7401 if (i == 3 || i == 2)
7402 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7403 else if (i == 1)
7404 /* Succeeds or fails, depending on SW or HW vertex processing. */
7405 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7407 hr = IDirect3DDevice9_EndScene(device);
7408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7410 color = getPixelColor(device, 480, 350);
7411 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7412 * as well.
7414 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7415 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7416 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7417 * refrast's result.
7419 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7421 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7422 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7423 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7426 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7428 IDirect3DDevice9_SetVertexShader(device, NULL);
7429 IDirect3DDevice9_SetPixelShader(device, NULL);
7430 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7432 IDirect3DVertexShader9_Release(swapped_shader);
7435 for (i = 1; i <= 3; ++i)
7437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7438 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7439 if(i == 3) {
7440 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
7441 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7442 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
7443 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7444 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7445 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7446 } else if(i == 2){
7447 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
7448 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7449 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
7450 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7451 } else if(i == 1) {
7452 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
7453 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7454 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
7455 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7458 hr = IDirect3DDevice9_BeginScene(device);
7459 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7461 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
7462 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7463 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
7464 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7466 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7468 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
7469 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7471 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
7472 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7473 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
7474 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7475 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7476 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7478 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
7479 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7480 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
7481 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7482 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7483 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7485 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
7486 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7488 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7490 hr = IDirect3DDevice9_EndScene(device);
7491 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7493 IDirect3DDevice9_SetVertexShader(device, NULL);
7494 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7495 IDirect3DDevice9_SetPixelShader(device, NULL);
7497 color = getPixelColor(device, 160, 360);
7498 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7499 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7500 color = getPixelColor(device, 480, 360);
7501 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7502 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7503 color = getPixelColor(device, 160, 120);
7504 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7505 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7506 color = getPixelColor(device, 480, 160);
7507 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7508 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7510 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7511 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7513 IDirect3DVertexShader9_Release(texcoord_color_shader);
7514 IDirect3DVertexShader9_Release(color_color_shader);
7517 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
7518 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
7519 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
7520 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
7522 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
7523 IDirect3DVertexDeclaration9_Release(decl_color_color);
7524 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
7525 IDirect3DVertexDeclaration9_Release(decl_color_float);
7527 IDirect3DPixelShader9_Release(ps);
7528 refcount = IDirect3DDevice9_Release(device);
7529 ok(!refcount, "Device has %u references left.\n", refcount);
7530 done:
7531 IDirect3D9_Release(d3d);
7532 DestroyWindow(window);
7535 static void srgbtexture_test(void)
7537 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
7538 * texture stage state to render a quad using that texture. The resulting
7539 * color components should be 0x36 (~ 0.21), per this formula:
7540 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
7541 * This is true where srgb_color > 0.04045. */
7542 struct IDirect3DTexture9 *texture;
7543 struct IDirect3DSurface9 *surface;
7544 IDirect3DDevice9 *device;
7545 IDirect3D9 *d3d;
7546 D3DCOLOR color;
7547 ULONG refcount;
7548 HWND window;
7549 HRESULT hr;
7551 static const float quad[] =
7553 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
7554 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7555 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
7556 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
7559 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7560 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7561 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7562 ok(!!d3d, "Failed to create a D3D object.\n");
7563 if (!(device = create_device(d3d, window, window, TRUE)))
7565 skip("Failed to create a D3D device, skipping tests.\n");
7566 goto done;
7569 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
7570 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
7572 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
7573 IDirect3DDevice9_Release(device);
7574 goto done;
7577 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7578 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7579 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7580 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
7582 fill_surface(surface, 0xff7f7f7f, 0);
7583 IDirect3DSurface9_Release(surface);
7585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7586 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7587 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7588 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7590 hr = IDirect3DDevice9_BeginScene(device);
7591 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7593 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
7594 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
7595 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7596 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7597 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
7598 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7600 hr = IDirect3DDevice9_EndScene(device);
7601 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7603 color = getPixelColor(device, 320, 240);
7604 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
7606 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7607 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7609 IDirect3DTexture9_Release(texture);
7610 refcount = IDirect3DDevice9_Release(device);
7611 ok(!refcount, "Device has %u references left.\n", refcount);
7612 done:
7613 IDirect3D9_Release(d3d);
7614 DestroyWindow(window);
7617 static void shademode_test(void)
7619 /* Render a quad and try all of the different fixed function shading models. */
7620 DWORD color0_gouraud = 0, color1_gouraud = 0;
7621 DWORD primtype = D3DPT_TRIANGLESTRIP;
7622 IDirect3DVertexBuffer9 *vb_strip;
7623 IDirect3DVertexBuffer9 *vb_list;
7624 DWORD shademode = D3DSHADE_FLAT;
7625 IDirect3DDevice9 *device;
7626 DWORD color0, color1;
7627 void *data = NULL;
7628 IDirect3D9 *d3d;
7629 ULONG refcount;
7630 HWND window;
7631 HRESULT hr;
7632 UINT i, j;
7634 static const struct
7636 struct vec3 position;
7637 DWORD diffuse;
7639 quad_strip[] =
7641 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
7642 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
7643 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
7644 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
7646 quad_list[] =
7648 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
7649 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
7650 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
7652 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
7653 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
7654 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
7657 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7658 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7659 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7660 ok(!!d3d, "Failed to create a D3D object.\n");
7661 if (!(device = create_device(d3d, window, window, TRUE)))
7663 skip("Failed to create a D3D device, skipping tests.\n");
7664 goto done;
7667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7673 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7674 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7675 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7676 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7677 memcpy(data, quad_strip, sizeof(quad_strip));
7678 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7679 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7681 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7682 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7683 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7684 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7685 memcpy(data, quad_list, sizeof(quad_list));
7686 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7687 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7689 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
7690 * the color fixups we have to do for FLAT shading will be dependent on that. */
7691 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7692 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7694 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7695 for (j=0; j<2; j++) {
7697 /* Inner loop just changes the D3DRS_SHADEMODE */
7698 for (i=0; i<3; i++) {
7699 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7700 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7703 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7705 hr = IDirect3DDevice9_BeginScene(device);
7706 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7707 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7708 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7709 hr = IDirect3DDevice9_EndScene(device);
7710 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7712 /* Sample two spots from the output */
7713 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7714 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7715 switch(shademode) {
7716 case D3DSHADE_FLAT:
7717 /* Should take the color of the first vertex of each triangle */
7718 if (0)
7720 /* This test depends on EXT_provoking_vertex being
7721 * available. This extension is currently (20090810)
7722 * not common enough to let the test fail if it isn't
7723 * present. */
7724 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7725 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7727 shademode = D3DSHADE_GOURAUD;
7728 break;
7729 case D3DSHADE_GOURAUD:
7730 /* Should be an interpolated blend */
7732 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7733 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7734 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7735 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7737 color0_gouraud = color0;
7738 color1_gouraud = color1;
7740 shademode = D3DSHADE_PHONG;
7741 break;
7742 case D3DSHADE_PHONG:
7743 /* Should be the same as GOURAUD, since no hardware implements this */
7744 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7745 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7746 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7747 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7749 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7750 color0_gouraud, color0);
7751 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7752 color1_gouraud, color1);
7753 break;
7757 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7758 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7760 /* Now, do it all over again with a TRIANGLELIST */
7761 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7762 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7763 primtype = D3DPT_TRIANGLELIST;
7764 shademode = D3DSHADE_FLAT;
7767 IDirect3DVertexBuffer9_Release(vb_strip);
7768 IDirect3DVertexBuffer9_Release(vb_list);
7769 refcount = IDirect3DDevice9_Release(device);
7770 ok(!refcount, "Device has %u references left.\n", refcount);
7771 done:
7772 IDirect3D9_Release(d3d);
7773 DestroyWindow(window);
7776 static void test_blend(void)
7778 IDirect3DSurface9 *backbuffer, *offscreen;
7779 IDirect3DTexture9 *offscreenTexture;
7780 IDirect3DDevice9 *device;
7781 IDirect3D9 *d3d;
7782 D3DCOLOR color;
7783 ULONG refcount;
7784 HWND window;
7785 HRESULT hr;
7787 static const struct
7789 struct vec3 position;
7790 DWORD diffuse;
7792 quad1[] =
7794 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
7795 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
7796 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
7797 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
7799 quad2[] =
7801 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
7802 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
7803 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
7804 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
7806 static const float composite_quad[][5] =
7808 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7809 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7810 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7811 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7814 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7815 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7816 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7817 ok(!!d3d, "Failed to create a D3D object.\n");
7818 if (!(device = create_device(d3d, window, window, TRUE)))
7820 skip("Failed to create a D3D device, skipping tests.\n");
7821 goto done;
7824 /* Clear the render target with alpha = 0.5 */
7825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
7826 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7828 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
7829 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7830 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7832 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7833 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7835 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7836 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7838 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7839 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7841 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7842 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7843 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7844 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7846 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7847 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7848 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7850 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7853 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7854 hr = IDirect3DDevice9_BeginScene(device);
7855 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7857 /* Draw two quads, one with src alpha blending, one with dest alpha
7858 * blending. */
7859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7860 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7862 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7864 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7867 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7869 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7871 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7873 /* Switch to the offscreen buffer, and redo the testing. The offscreen
7874 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
7875 * "don't work" on render targets without alpha channel, they give
7876 * essentially ZERO and ONE blend factors. */
7877 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7878 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
7880 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7882 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7883 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7884 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7885 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7887 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7889 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7890 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7892 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7893 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7894 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7896 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7897 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7899 /* Render the offscreen texture onto the frame buffer to be able to
7900 * compare it regularly. Disable alpha blending for the final
7901 * composition. */
7902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7903 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7904 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7905 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7907 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7908 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7910 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7912 hr = IDirect3DDevice9_EndScene(device);
7913 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7915 color = getPixelColor(device, 160, 360);
7916 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7917 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7919 color = getPixelColor(device, 160, 120);
7920 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7921 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7923 color = getPixelColor(device, 480, 360);
7924 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7925 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7927 color = getPixelColor(device, 480, 120);
7928 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7929 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7931 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7933 IDirect3DSurface9_Release(backbuffer);
7934 IDirect3DTexture9_Release(offscreenTexture);
7935 IDirect3DSurface9_Release(offscreen);
7936 refcount = IDirect3DDevice9_Release(device);
7937 ok(!refcount, "Device has %u references left.\n", refcount);
7938 done:
7939 IDirect3D9_Release(d3d);
7940 DestroyWindow(window);
7943 static void fixed_function_decl_test(void)
7945 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7946 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7947 IDirect3DVertexBuffer9 *vb, *vb2;
7948 IDirect3DDevice9 *device;
7949 BOOL s_ok, ub_ok, f_ok;
7950 DWORD color, size, i;
7951 IDirect3D9 *d3d;
7952 ULONG refcount;
7953 D3DCAPS9 caps;
7954 HWND window;
7955 void *data;
7956 HRESULT hr;
7958 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7959 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7960 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7961 D3DDECL_END()
7963 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7964 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7965 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7966 D3DDECL_END()
7968 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7969 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7970 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7971 D3DDECL_END()
7973 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7974 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7975 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7976 D3DDECL_END()
7978 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7979 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7980 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7981 D3DDECL_END()
7983 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7984 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7985 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7986 D3DDECL_END()
7988 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7989 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7990 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7991 D3DDECL_END()
7993 static const struct
7995 struct vec3 position;
7996 DWORD diffuse;
7998 quad1[] = /* D3DCOLOR */
8000 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8001 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8002 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8003 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8005 quad2[] = /* UBYTE4N */
8007 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8008 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8009 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8010 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8012 static const struct
8014 struct vec3 position;
8015 struct { unsigned short x, y, z, w; } color;
8017 quad3[] = /* USHORT4N */
8019 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8020 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8021 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8022 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8024 static const struct
8026 struct vec3 position;
8027 struct vec4 color;
8029 quad4[] =
8031 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8032 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8033 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8034 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8036 static const DWORD colors[] =
8038 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8039 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8040 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8041 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8042 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8043 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8044 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8045 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8046 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8047 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8048 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8049 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8050 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8051 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8052 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8053 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8055 static const float quads[] =
8057 -1.0f, -1.0f, 0.1f,
8058 -1.0f, 0.0f, 0.1f,
8059 0.0f, -1.0f, 0.1f,
8060 0.0f, 0.0f, 0.1f,
8062 0.0f, -1.0f, 0.1f,
8063 0.0f, 0.0f, 0.1f,
8064 1.0f, -1.0f, 0.1f,
8065 1.0f, 0.0f, 0.1f,
8067 0.0f, 0.0f, 0.1f,
8068 0.0f, 1.0f, 0.1f,
8069 1.0f, 0.0f, 0.1f,
8070 1.0f, 1.0f, 0.1f,
8072 -1.0f, 0.0f, 0.1f,
8073 -1.0f, 1.0f, 0.1f,
8074 0.0f, 0.0f, 0.1f,
8075 0.0f, 1.0f, 0.1f,
8077 static const struct
8079 struct vec4 position;
8080 DWORD diffuse;
8082 quad_transformed[] =
8084 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8085 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8086 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8087 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8090 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8091 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8092 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8093 ok(!!d3d, "Failed to create a D3D object.\n");
8094 if (!(device = create_device(d3d, window, window, TRUE)))
8096 skip("Failed to create a D3D device, skipping tests.\n");
8097 goto done;
8100 memset(&caps, 0, sizeof(caps));
8101 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8102 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8105 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8107 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8108 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8109 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8110 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8111 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8112 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8113 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8114 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8115 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8116 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8117 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8118 } else {
8119 trace("D3DDTCAPS_UBYTE4N not supported\n");
8120 dcl_ubyte_2 = NULL;
8121 dcl_ubyte = NULL;
8123 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8124 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8125 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8126 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8128 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8129 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8130 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8131 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8134 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8136 hr = IDirect3DDevice9_BeginScene(device);
8137 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8139 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8140 if (dcl_color)
8142 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8143 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8145 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8148 /* Tests with non-standard fixed function types fail on the refrast. The
8149 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8150 * All those differences even though we're using software vertex
8151 * processing. Doh! */
8152 if (dcl_ubyte)
8154 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8155 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8157 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8158 ub_ok = SUCCEEDED(hr);
8161 if (dcl_short)
8163 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8164 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8166 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8167 s_ok = SUCCEEDED(hr);
8170 if (dcl_float)
8172 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8173 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8175 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8176 f_ok = SUCCEEDED(hr);
8179 hr = IDirect3DDevice9_EndScene(device);
8180 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8182 if(dcl_short) {
8183 color = getPixelColor(device, 480, 360);
8184 ok(color == 0x000000ff || !s_ok,
8185 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8187 if(dcl_ubyte) {
8188 color = getPixelColor(device, 160, 120);
8189 ok(color == 0x0000ffff || !ub_ok,
8190 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8192 if(dcl_color) {
8193 color = getPixelColor(device, 160, 360);
8194 ok(color == 0x00ffff00,
8195 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8197 if(dcl_float) {
8198 color = getPixelColor(device, 480, 120);
8199 ok(color == 0x00ff0000 || !f_ok,
8200 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8202 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8204 /* The following test with vertex buffers doesn't serve to find out new
8205 * information from windows. It is a plain regression test because wined3d
8206 * uses different codepaths for attribute conversion with vertex buffers.
8207 * It makes sure that the vertex buffer one works, while the above tests
8208 * whether the immediate mode code works. */
8209 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8210 hr = IDirect3DDevice9_BeginScene(device);
8211 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8213 if (dcl_color)
8215 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8216 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8217 memcpy(data, quad1, sizeof(quad1));
8218 hr = IDirect3DVertexBuffer9_Unlock(vb);
8219 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8220 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8221 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8222 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8223 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8224 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8225 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8228 if (dcl_ubyte)
8230 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8231 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8232 memcpy(data, quad2, sizeof(quad2));
8233 hr = IDirect3DVertexBuffer9_Unlock(vb);
8234 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8235 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8236 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8237 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8238 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8239 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8240 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8241 ub_ok = SUCCEEDED(hr);
8244 if (dcl_short)
8246 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8247 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8248 memcpy(data, quad3, sizeof(quad3));
8249 hr = IDirect3DVertexBuffer9_Unlock(vb);
8250 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8251 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8252 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8253 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8254 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8255 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8256 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8257 s_ok = SUCCEEDED(hr);
8260 if (dcl_float)
8262 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8263 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8264 memcpy(data, quad4, sizeof(quad4));
8265 hr = IDirect3DVertexBuffer9_Unlock(vb);
8266 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8267 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8268 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8269 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8270 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8271 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8272 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8273 f_ok = SUCCEEDED(hr);
8276 hr = IDirect3DDevice9_EndScene(device);
8277 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8279 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8280 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8281 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8284 if(dcl_short) {
8285 color = getPixelColor(device, 480, 360);
8286 ok(color == 0x000000ff || !s_ok,
8287 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8289 if(dcl_ubyte) {
8290 color = getPixelColor(device, 160, 120);
8291 ok(color == 0x0000ffff || !ub_ok,
8292 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8294 if(dcl_color) {
8295 color = getPixelColor(device, 160, 360);
8296 ok(color == 0x00ffff00,
8297 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8299 if(dcl_float) {
8300 color = getPixelColor(device, 480, 120);
8301 ok(color == 0x00ff0000 || !f_ok,
8302 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8304 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8306 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8307 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8309 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
8310 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8311 memcpy(data, quad_transformed, sizeof(quad_transformed));
8312 hr = IDirect3DVertexBuffer9_Unlock(vb);
8313 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8315 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
8316 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8318 hr = IDirect3DDevice9_BeginScene(device);
8319 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8320 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
8321 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8322 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8323 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8324 hr = IDirect3DDevice9_EndScene(device);
8325 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8327 color = getPixelColor(device, 88, 108);
8328 ok(color == 0x000000ff,
8329 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8330 color = getPixelColor(device, 92, 108);
8331 ok(color == 0x000000ff,
8332 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8333 color = getPixelColor(device, 88, 112);
8334 ok(color == 0x000000ff,
8335 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8336 color = getPixelColor(device, 92, 112);
8337 ok(color == 0x00ffff00,
8338 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8340 color = getPixelColor(device, 568, 108);
8341 ok(color == 0x000000ff,
8342 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8343 color = getPixelColor(device, 572, 108);
8344 ok(color == 0x000000ff,
8345 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8346 color = getPixelColor(device, 568, 112);
8347 ok(color == 0x00ffff00,
8348 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8349 color = getPixelColor(device, 572, 112);
8350 ok(color == 0x000000ff,
8351 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8353 color = getPixelColor(device, 88, 298);
8354 ok(color == 0x000000ff,
8355 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8356 color = getPixelColor(device, 92, 298);
8357 ok(color == 0x00ffff00,
8358 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8359 color = getPixelColor(device, 88, 302);
8360 ok(color == 0x000000ff,
8361 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8362 color = getPixelColor(device, 92, 302);
8363 ok(color == 0x000000ff,
8364 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8366 color = getPixelColor(device, 568, 298);
8367 ok(color == 0x00ffff00,
8368 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8369 color = getPixelColor(device, 572, 298);
8370 ok(color == 0x000000ff,
8371 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8372 color = getPixelColor(device, 568, 302);
8373 ok(color == 0x000000ff,
8374 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8375 color = getPixelColor(device, 572, 302);
8376 ok(color == 0x000000ff,
8377 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8379 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8381 /* This test is pointless without those two declarations: */
8382 if((!dcl_color_2) || (!dcl_ubyte_2)) {
8383 skip("color-ubyte switching test declarations aren't supported\n");
8384 goto out;
8387 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
8388 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8389 memcpy(data, quads, sizeof(quads));
8390 hr = IDirect3DVertexBuffer9_Unlock(vb);
8391 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8392 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
8393 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8394 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8395 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
8396 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8397 memcpy(data, colors, sizeof(colors));
8398 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8399 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8401 for(i = 0; i < 2; i++) {
8402 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8403 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8405 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
8406 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8407 if(i == 0) {
8408 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
8409 } else {
8410 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
8412 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8414 hr = IDirect3DDevice9_BeginScene(device);
8415 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8417 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8418 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8419 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8420 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8421 ub_ok = SUCCEEDED(hr);
8423 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
8424 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8425 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8426 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8428 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8429 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8430 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8431 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8432 ub_ok = (SUCCEEDED(hr) && ub_ok);
8434 hr = IDirect3DDevice9_EndScene(device);
8435 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8437 if(i == 0) {
8438 color = getPixelColor(device, 480, 360);
8439 ok(color == 0x00ff0000,
8440 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
8441 color = getPixelColor(device, 160, 120);
8442 ok(color == 0x00ffffff,
8443 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8444 color = getPixelColor(device, 160, 360);
8445 ok(color == 0x000000ff || !ub_ok,
8446 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8447 color = getPixelColor(device, 480, 120);
8448 ok(color == 0x000000ff || !ub_ok,
8449 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8450 } else {
8451 color = getPixelColor(device, 480, 360);
8452 ok(color == 0x000000ff,
8453 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
8454 color = getPixelColor(device, 160, 120);
8455 ok(color == 0x00ffffff,
8456 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8457 color = getPixelColor(device, 160, 360);
8458 ok(color == 0x00ff0000 || !ub_ok,
8459 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8460 color = getPixelColor(device, 480, 120);
8461 ok(color == 0x00ff0000 || !ub_ok,
8462 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8464 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8467 IDirect3DVertexBuffer9_Release(vb2);
8468 out:
8469 IDirect3DVertexBuffer9_Release(vb);
8470 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
8471 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
8472 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
8473 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
8474 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
8475 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
8476 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
8477 refcount = IDirect3DDevice9_Release(device);
8478 ok(!refcount, "Device has %u references left.\n", refcount);
8479 done:
8480 IDirect3D9_Release(d3d);
8481 DestroyWindow(window);
8484 static void test_vshader_float16(void)
8486 IDirect3DVertexDeclaration9 *vdecl = NULL;
8487 IDirect3DVertexBuffer9 *buffer = NULL;
8488 IDirect3DVertexShader9 *shader;
8489 IDirect3DDevice9 *device;
8490 IDirect3D9 *d3d;
8491 ULONG refcount;
8492 D3DCAPS9 caps;
8493 DWORD color;
8494 HWND window;
8495 void *data;
8496 HRESULT hr;
8498 static const D3DVERTEXELEMENT9 decl_elements[] =
8500 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8501 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8502 D3DDECL_END()
8504 static const DWORD shader_code[] =
8506 0xfffe0101, /* vs_1_1 */
8507 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8508 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8509 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8510 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8511 0x0000ffff,
8513 static const struct vertex_float16color
8515 float x, y, z;
8516 DWORD c1, c2;
8518 quad[] =
8520 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
8521 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8522 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
8523 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8525 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
8526 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8527 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
8528 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8530 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
8531 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8532 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
8533 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8535 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
8536 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8537 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
8538 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8541 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8542 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8543 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8544 ok(!!d3d, "Failed to create a D3D object.\n");
8545 if (!(device = create_device(d3d, window, window, TRUE)))
8547 skip("Failed to create a D3D device, skipping tests.\n");
8548 goto done;
8551 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8552 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8553 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8555 skip("No vs_3_0 support, skipping tests.\n");
8556 IDirect3DDevice9_Release(device);
8557 goto done;
8560 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
8561 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8563 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
8564 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
8565 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8566 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8567 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8568 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8570 hr = IDirect3DDevice9_BeginScene(device);
8571 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8572 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
8573 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
8575 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
8577 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
8579 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
8581 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8582 hr = IDirect3DDevice9_EndScene(device);
8583 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8585 color = getPixelColor(device, 480, 360);
8586 ok(color == 0x00ff0000,
8587 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8588 color = getPixelColor(device, 160, 120);
8589 ok(color == 0x00000000,
8590 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8591 color = getPixelColor(device, 160, 360);
8592 ok(color == 0x0000ff00,
8593 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8594 color = getPixelColor(device, 480, 120);
8595 ok(color == 0x000000ff,
8596 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8597 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8599 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
8600 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8602 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
8603 D3DPOOL_MANAGED, &buffer, NULL);
8604 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
8605 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
8606 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
8607 memcpy(data, quad, sizeof(quad));
8608 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8609 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
8610 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
8611 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8613 hr = IDirect3DDevice9_BeginScene(device);
8614 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8615 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8616 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8617 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8618 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8619 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8620 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8621 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
8622 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8623 hr = IDirect3DDevice9_EndScene(device);
8624 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8626 color = getPixelColor(device, 480, 360);
8627 ok(color == 0x00ff0000,
8628 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8629 color = getPixelColor(device, 160, 120);
8630 ok(color == 0x00000000,
8631 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8632 color = getPixelColor(device, 160, 360);
8633 ok(color == 0x0000ff00,
8634 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8635 color = getPixelColor(device, 480, 120);
8636 ok(color == 0x000000ff,
8637 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8638 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8640 IDirect3DVertexDeclaration9_Release(vdecl);
8641 IDirect3DVertexShader9_Release(shader);
8642 IDirect3DVertexBuffer9_Release(buffer);
8643 refcount = IDirect3DDevice9_Release(device);
8644 ok(!refcount, "Device has %u references left.\n", refcount);
8645 done:
8646 IDirect3D9_Release(d3d);
8647 DestroyWindow(window);
8650 static void conditional_np2_repeat_test(void)
8652 IDirect3DTexture9 *texture;
8653 IDirect3DDevice9 *device;
8654 D3DLOCKED_RECT rect;
8655 unsigned int x, y;
8656 DWORD *dst, color;
8657 IDirect3D9 *d3d;
8658 ULONG refcount;
8659 D3DCAPS9 caps;
8660 HWND window;
8661 HRESULT hr;
8663 static const float quad[] =
8665 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
8666 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
8667 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
8668 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
8671 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8672 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8673 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8674 ok(!!d3d, "Failed to create a D3D object.\n");
8675 if (!(device = create_device(d3d, window, window, TRUE)))
8677 skip("Failed to create a D3D device, skipping tests.\n");
8678 goto done;
8681 memset(&caps, 0, sizeof(caps));
8682 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8683 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8684 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8686 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
8687 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
8688 "Card has conditional NP2 support without power of two restriction set\n");
8690 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8692 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8693 IDirect3DDevice9_Release(device);
8694 goto done;
8696 else
8698 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8699 IDirect3DDevice9_Release(device);
8700 goto done;
8703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
8704 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8706 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8707 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8709 memset(&rect, 0, sizeof(rect));
8710 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8711 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8712 for(y = 0; y < 10; y++) {
8713 for(x = 0; x < 10; x++) {
8714 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8715 if(x == 0 || x == 9 || y == 0 || y == 9) {
8716 *dst = 0x00ff0000;
8717 } else {
8718 *dst = 0x000000ff;
8722 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8723 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8725 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8726 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8728 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8729 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8730 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8731 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8732 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8733 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8734 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8736 hr = IDirect3DDevice9_BeginScene(device);
8737 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8738 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8739 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8740 hr = IDirect3DDevice9_EndScene(device);
8741 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8743 color = getPixelColor(device, 1, 1);
8744 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8745 color = getPixelColor(device, 639, 479);
8746 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8748 color = getPixelColor(device, 135, 101);
8749 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8750 color = getPixelColor(device, 140, 101);
8751 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8752 color = getPixelColor(device, 135, 105);
8753 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8754 color = getPixelColor(device, 140, 105);
8755 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8757 color = getPixelColor(device, 135, 376);
8758 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8759 color = getPixelColor(device, 140, 376);
8760 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8761 color = getPixelColor(device, 135, 379);
8762 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8763 color = getPixelColor(device, 140, 379);
8764 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8766 color = getPixelColor(device, 500, 101);
8767 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8768 color = getPixelColor(device, 504, 101);
8769 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8770 color = getPixelColor(device, 500, 105);
8771 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8772 color = getPixelColor(device, 504, 105);
8773 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8775 color = getPixelColor(device, 500, 376);
8776 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8777 color = getPixelColor(device, 504, 376);
8778 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8779 color = getPixelColor(device, 500, 380);
8780 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8781 color = getPixelColor(device, 504, 380);
8782 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8784 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8786 IDirect3DTexture9_Release(texture);
8787 refcount = IDirect3DDevice9_Release(device);
8788 ok(!refcount, "Device has %u references left.\n", refcount);
8789 done:
8790 IDirect3D9_Release(d3d);
8791 DestroyWindow(window);
8794 static void vface_register_test(void)
8796 IDirect3DSurface9 *surface, *backbuffer;
8797 IDirect3DVertexShader9 *vshader;
8798 IDirect3DPixelShader9 *shader;
8799 IDirect3DTexture9 *texture;
8800 IDirect3DDevice9 *device;
8801 IDirect3D9 *d3d;
8802 ULONG refcount;
8803 D3DCAPS9 caps;
8804 DWORD color;
8805 HWND window;
8806 HRESULT hr;
8808 static const DWORD shader_code[] =
8810 0xffff0300, /* ps_3_0 */
8811 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8812 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8813 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8814 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8815 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8816 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8817 0x0000ffff /* END */
8819 static const DWORD vshader_code[] =
8821 0xfffe0300, /* vs_3_0 */
8822 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8823 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8824 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8825 0x0000ffff /* end */
8827 static const float quad[] =
8829 -1.0f, -1.0f, 0.1f,
8830 1.0f, -1.0f, 0.1f,
8831 -1.0f, 0.0f, 0.1f,
8833 1.0f, -1.0f, 0.1f,
8834 1.0f, 0.0f, 0.1f,
8835 -1.0f, 0.0f, 0.1f,
8837 -1.0f, 0.0f, 0.1f,
8838 -1.0f, 1.0f, 0.1f,
8839 1.0f, 0.0f, 0.1f,
8841 1.0f, 0.0f, 0.1f,
8842 -1.0f, 1.0f, 0.1f,
8843 1.0f, 1.0f, 0.1f,
8845 static const float blit[] =
8847 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
8848 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
8849 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
8850 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
8853 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8854 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8855 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8856 ok(!!d3d, "Failed to create a D3D object.\n");
8857 if (!(device = create_device(d3d, window, window, TRUE)))
8859 skip("Failed to create a D3D device, skipping tests.\n");
8860 goto done;
8863 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8864 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8865 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8867 skip("No shader model 3 support, skipping tests.\n");
8868 IDirect3DDevice9_Release(device);
8869 goto done;
8872 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8873 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8874 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8875 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8876 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8877 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8878 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8879 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8881 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
8882 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8884 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8885 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8886 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8887 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8888 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8889 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8891 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8892 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8894 hr = IDirect3DDevice9_BeginScene(device);
8895 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8897 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8898 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8899 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8900 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8901 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8903 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8904 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8905 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8907 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8909 /* Blit the texture onto the back buffer to make it visible */
8910 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8911 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8912 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8913 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8914 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8915 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8916 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8917 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
8918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8919 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
8920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8921 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8923 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8925 hr = IDirect3DDevice9_EndScene(device);
8926 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8928 color = getPixelColor(device, 160, 360);
8929 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8930 color = getPixelColor(device, 160, 120);
8931 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8932 color = getPixelColor(device, 480, 360);
8933 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8934 color = getPixelColor(device, 480, 120);
8935 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8937 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8939 IDirect3DPixelShader9_Release(shader);
8940 IDirect3DVertexShader9_Release(vshader);
8941 IDirect3DSurface9_Release(surface);
8942 IDirect3DSurface9_Release(backbuffer);
8943 IDirect3DTexture9_Release(texture);
8944 refcount = IDirect3DDevice9_Release(device);
8945 ok(!refcount, "Device has %u references left.\n", refcount);
8946 done:
8947 IDirect3D9_Release(d3d);
8948 DestroyWindow(window);
8951 static void fixed_function_bumpmap_test(void)
8953 IDirect3DVertexDeclaration9 *vertex_declaration;
8954 IDirect3DTexture9 *texture, *tex1, *tex2;
8955 D3DLOCKED_RECT locked_rect;
8956 IDirect3DDevice9 *device;
8957 BOOL L6V5U5_supported;
8958 float scale, offset;
8959 IDirect3D9 *d3d;
8960 unsigned int i;
8961 D3DCOLOR color;
8962 ULONG refcount;
8963 D3DCAPS9 caps;
8964 HWND window;
8965 HRESULT hr;
8967 static const float quad[][7] =
8969 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8970 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8971 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8972 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8974 static const D3DVERTEXELEMENT9 decl_elements[] =
8976 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8977 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8978 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8979 D3DDECL_END()
8981 /* use asymmetric matrix to test loading */
8982 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
8984 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8985 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8986 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8987 ok(!!d3d, "Failed to create a D3D object.\n");
8988 if (!(device = create_device(d3d, window, window, TRUE)))
8990 skip("Failed to create a D3D device, skipping tests.\n");
8991 goto done;
8994 memset(&caps, 0, sizeof(caps));
8995 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8996 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8997 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
8999 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9000 IDirect3DDevice9_Release(device);
9001 goto done;
9004 /* This check is disabled, some Windows drivers do not handle
9005 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9006 * supported, but after that bump mapping works properly. So just test if
9007 * the format is generally supported, and check the BUMPENVMAP flag. */
9008 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9009 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9010 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9011 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9013 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9014 IDirect3DDevice9_Release(device);
9015 return;
9018 /* Generate the textures */
9019 generate_bumpmap_textures(device);
9021 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9022 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9024 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9026 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9027 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9028 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9030 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9031 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9032 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9033 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9034 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9035 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9037 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9038 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9039 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9040 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9041 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9042 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9044 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9045 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9047 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9048 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9051 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9053 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9054 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9055 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9056 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9058 hr = IDirect3DDevice9_BeginScene(device);
9059 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9064 hr = IDirect3DDevice9_EndScene(device);
9065 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9067 color = getPixelColor(device, 240, 60);
9068 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9069 color = getPixelColor(device, 400, 60);
9070 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9071 color = getPixelColor(device, 80, 180);
9072 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9073 color = getPixelColor(device, 560, 180);
9074 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9075 color = getPixelColor(device, 80, 300);
9076 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9077 color = getPixelColor(device, 560, 300);
9078 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9079 color = getPixelColor(device, 240, 420);
9080 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9081 color = getPixelColor(device, 400, 420);
9082 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9083 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9084 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9086 for(i = 0; i < 2; i++) {
9087 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9088 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9089 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9090 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9091 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9092 IDirect3DTexture9_Release(texture); /* To destroy it */
9095 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9097 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9098 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9099 IDirect3DDevice9_Release(device);
9100 goto done;
9103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9104 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9105 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9106 * would only make this test more complicated
9108 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9109 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9110 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9111 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9113 memset(&locked_rect, 0, sizeof(locked_rect));
9114 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9115 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9116 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9117 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9118 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9120 memset(&locked_rect, 0, sizeof(locked_rect));
9121 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9122 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9123 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9124 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9125 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9127 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9128 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9129 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9130 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9132 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9133 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9134 scale = 2.0;
9135 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9136 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9137 offset = 0.1;
9138 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9139 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9141 hr = IDirect3DDevice9_BeginScene(device);
9142 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9143 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9144 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9145 hr = IDirect3DDevice9_EndScene(device);
9146 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9148 color = getPixelColor(device, 320, 240);
9149 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9150 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9151 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9153 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9155 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9157 /* Check a result scale factor > 1.0 */
9158 scale = 10;
9159 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9160 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9161 offset = 10;
9162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9163 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9165 hr = IDirect3DDevice9_BeginScene(device);
9166 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9167 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9168 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9169 hr = IDirect3DDevice9_EndScene(device);
9170 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9172 color = getPixelColor(device, 320, 240);
9173 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9175 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9177 /* Check clamping in the scale factor calculation */
9178 scale = 1000;
9179 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9180 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9181 offset = -1;
9182 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9183 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9185 hr = IDirect3DDevice9_BeginScene(device);
9186 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9188 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9189 hr = IDirect3DDevice9_EndScene(device);
9190 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9192 color = getPixelColor(device, 320, 240);
9193 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9194 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9195 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9197 IDirect3DTexture9_Release(tex1);
9198 IDirect3DTexture9_Release(tex2);
9199 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9200 refcount = IDirect3DDevice9_Release(device);
9201 ok(!refcount, "Device has %u references left.\n", refcount);
9202 done:
9203 IDirect3D9_Release(d3d);
9204 DestroyWindow(window);
9207 static void stencil_cull_test(void)
9209 IDirect3DDevice9 *device;
9210 IDirect3D9 *d3d;
9211 ULONG refcount;
9212 D3DCAPS9 caps;
9213 HWND window;
9214 HRESULT hr;
9215 static const float quad1[] =
9217 -1.0, -1.0, 0.1,
9218 0.0, -1.0, 0.1,
9219 -1.0, 0.0, 0.1,
9220 0.0, 0.0, 0.1,
9222 static const float quad2[] =
9224 0.0, -1.0, 0.1,
9225 1.0, -1.0, 0.1,
9226 0.0, 0.0, 0.1,
9227 1.0, 0.0, 0.1,
9229 static const float quad3[] =
9231 0.0, 0.0, 0.1,
9232 1.0, 0.0, 0.1,
9233 0.0, 1.0, 0.1,
9234 1.0, 1.0, 0.1,
9236 static const float quad4[] =
9238 -1.0, 0.0, 0.1,
9239 0.0, 0.0, 0.1,
9240 -1.0, 1.0, 0.1,
9241 0.0, 1.0, 0.1,
9243 struct
9245 struct vec3 position;
9246 DWORD diffuse;
9248 painter[] =
9250 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
9251 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
9252 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
9253 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
9255 static const WORD indices_cw[] = {0, 1, 3};
9256 static const WORD indices_ccw[] = {0, 2, 3};
9257 unsigned int i;
9258 DWORD color;
9260 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9261 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9263 ok(!!d3d, "Failed to create a D3D object.\n");
9264 if (!(device = create_device(d3d, window, window, TRUE)))
9266 skip("Cannot create a device with a D24S8 stencil buffer.\n");
9267 DestroyWindow(window);
9268 IDirect3D9_Release(d3d);
9269 return;
9271 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9272 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9273 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
9275 skip("No two sided stencil support\n");
9276 goto cleanup;
9279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
9280 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9281 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9282 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
9284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9285 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
9286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9287 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
9288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
9289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
9291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
9293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
9295 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
9298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
9300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
9302 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
9305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9309 /* First pass: Fill the stencil buffer with some values... */
9310 hr = IDirect3DDevice9_BeginScene(device);
9311 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9314 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9315 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9316 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9317 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9318 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9319 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9320 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
9323 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9325 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9327 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9328 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9329 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9330 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9331 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9334 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9335 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9336 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9337 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9338 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9339 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9340 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
9343 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9344 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9345 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9346 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9347 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9348 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9349 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9351 hr = IDirect3DDevice9_EndScene(device);
9352 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
9355 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
9357 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
9359 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9361 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9363 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
9365 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9367 /* 2nd pass: Make the stencil values visible */
9368 hr = IDirect3DDevice9_BeginScene(device);
9369 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9370 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9371 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9372 for (i = 0; i < 16; ++i)
9374 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
9375 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9377 painter[0].diffuse = (i * 16); /* Creates shades of blue */
9378 painter[1].diffuse = (i * 16);
9379 painter[2].diffuse = (i * 16);
9380 painter[3].diffuse = (i * 16);
9381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
9382 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9384 hr = IDirect3DDevice9_EndScene(device);
9385 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9388 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9390 color = getPixelColor(device, 160, 420);
9391 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
9392 color = getPixelColor(device, 160, 300);
9393 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9395 color = getPixelColor(device, 480, 420);
9396 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
9397 color = getPixelColor(device, 480, 300);
9398 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
9400 color = getPixelColor(device, 160, 180);
9401 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
9402 color = getPixelColor(device, 160, 60);
9403 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
9405 color = getPixelColor(device, 480, 180);
9406 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
9407 color = getPixelColor(device, 480, 60);
9408 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9410 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9411 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9413 cleanup:
9414 refcount = IDirect3DDevice9_Release(device);
9415 ok(!refcount, "Device has %u references left.\n", refcount);
9416 IDirect3D9_Release(d3d);
9417 DestroyWindow(window);
9420 static void vpos_register_test(void)
9422 IDirect3DSurface9 *surface = NULL, *backbuffer;
9423 IDirect3DPixelShader9 *shader, *shader_frac;
9424 IDirect3DVertexShader9 *vshader;
9425 IDirect3DDevice9 *device;
9426 D3DLOCKED_RECT lr;
9427 IDirect3D9 *d3d;
9428 ULONG refcount;
9429 D3DCAPS9 caps;
9430 DWORD color;
9431 HWND window;
9432 HRESULT hr;
9433 DWORD *pos;
9435 static const DWORD shader_code[] =
9437 0xffff0300, /* ps_3_0 */
9438 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9439 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
9440 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
9441 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
9442 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
9443 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
9444 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
9445 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
9446 0x0000ffff /* end */
9448 static const DWORD shader_frac_code[] =
9450 0xffff0300, /* ps_3_0 */
9451 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
9452 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9453 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
9454 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
9455 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9456 0x0000ffff /* end */
9458 static const DWORD vshader_code[] =
9460 0xfffe0300, /* vs_3_0 */
9461 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9462 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9463 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9464 0x0000ffff /* end */
9466 static const float quad[] =
9468 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9469 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9470 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9471 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9473 float constant[4] = {1.0, 0.0, 320, 240};
9475 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9476 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9477 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9478 ok(!!d3d, "Failed to create a D3D object.\n");
9479 if (!(device = create_device(d3d, window, window, TRUE)))
9481 skip("Failed to create a D3D device, skipping tests.\n");
9482 goto done;
9485 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9486 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9487 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9489 skip("No shader model 3 support, skipping tests.\n");
9490 IDirect3DDevice9_Release(device);
9491 goto done;
9494 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9495 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9496 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9497 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9498 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9499 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9500 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
9501 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9502 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9503 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9504 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9505 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9506 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9507 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9508 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9509 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9511 hr = IDirect3DDevice9_BeginScene(device);
9512 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9513 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9514 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9516 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9517 hr = IDirect3DDevice9_EndScene(device);
9518 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9520 /* This has to be pixel exact */
9521 color = getPixelColor(device, 319, 239);
9522 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
9523 color = getPixelColor(device, 320, 239);
9524 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
9525 color = getPixelColor(device, 319, 240);
9526 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
9527 color = getPixelColor(device, 320, 240);
9528 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
9529 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9531 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
9532 &surface, NULL);
9533 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
9534 hr = IDirect3DDevice9_BeginScene(device);
9535 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9536 constant[2] = 16; constant[3] = 16;
9537 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9538 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9539 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9540 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9542 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9543 hr = IDirect3DDevice9_EndScene(device);
9544 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9546 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9547 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9549 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9550 color = *pos & 0x00ffffff;
9551 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
9552 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
9553 color = *pos & 0x00ffffff;
9554 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
9555 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
9556 color = *pos & 0x00ffffff;
9557 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
9558 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
9559 color = *pos & 0x00ffffff;
9560 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
9562 hr = IDirect3DSurface9_UnlockRect(surface);
9563 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9565 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
9566 * have full control over the multisampling setting inside this test
9568 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
9569 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9570 hr = IDirect3DDevice9_BeginScene(device);
9571 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9572 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9573 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9575 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9576 hr = IDirect3DDevice9_EndScene(device);
9577 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9579 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9580 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9582 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9583 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9585 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9586 color = *pos & 0x00ffffff;
9587 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
9589 hr = IDirect3DSurface9_UnlockRect(surface);
9590 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9592 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9593 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9594 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9595 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9596 IDirect3DPixelShader9_Release(shader);
9597 IDirect3DPixelShader9_Release(shader_frac);
9598 IDirect3DVertexShader9_Release(vshader);
9599 if(surface) IDirect3DSurface9_Release(surface);
9600 IDirect3DSurface9_Release(backbuffer);
9601 refcount = IDirect3DDevice9_Release(device);
9602 ok(!refcount, "Device has %u references left.\n", refcount);
9603 done:
9604 IDirect3D9_Release(d3d);
9605 DestroyWindow(window);
9608 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
9610 D3DCOLOR color;
9612 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
9613 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9614 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9615 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9616 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9618 ++r;
9619 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
9620 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9621 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9622 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9623 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9625 return TRUE;
9628 static void pointsize_test(void)
9630 float ptsize, ptsizemax_orig, ptsizemin_orig;
9631 IDirect3DSurface9 *rt, *backbuffer;
9632 IDirect3DTexture9 *tex1, *tex2;
9633 IDirect3DDevice9 *device;
9634 D3DLOCKED_RECT lr;
9635 IDirect3D9 *d3d;
9636 D3DCOLOR color;
9637 ULONG refcount;
9638 D3DCAPS9 caps;
9639 HWND window;
9640 HRESULT hr;
9642 static const RECT rect = {0, 0, 128, 128};
9643 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
9644 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
9645 static const float vertices[] =
9647 64.0f, 64.0f, 0.1f,
9648 128.0f, 64.0f, 0.1f,
9649 192.0f, 64.0f, 0.1f,
9650 256.0f, 64.0f, 0.1f,
9651 320.0f, 64.0f, 0.1f,
9652 384.0f, 64.0f, 0.1f,
9653 448.0f, 64.0f, 0.1f,
9654 512.0f, 64.0f, 0.1f,
9656 /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to
9657 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
9658 D3DMATRIX matrix =
9660 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
9661 0.0f, -2.0 / 480.0f, 0.0f, 0.0f,
9662 0.0f, 0.0f, 1.0f, 0.0f,
9663 -1.0f, 1.0f, 0.0f, 1.0f,
9664 }}};
9666 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9667 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9668 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9669 ok(!!d3d, "Failed to create a D3D object.\n");
9670 if (!(device = create_device(d3d, window, window, TRUE)))
9672 skip("Failed to create a D3D device, skipping tests.\n");
9673 goto done;
9676 memset(&caps, 0, sizeof(caps));
9677 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9678 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9679 if(caps.MaxPointSize < 32.0) {
9680 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
9681 IDirect3DDevice9_Release(device);
9682 goto done;
9685 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9686 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9688 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9689 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9690 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9691 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9692 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9694 hr = IDirect3DDevice9_BeginScene(device);
9695 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9697 ptsize = 15.0f;
9698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9699 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9701 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9703 ptsize = 31.0f;
9704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9705 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
9707 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9709 ptsize = 30.75f;
9710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9711 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9712 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
9713 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9715 if (caps.MaxPointSize >= 63.0f)
9717 ptsize = 63.0f;
9718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9719 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
9721 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9723 ptsize = 62.75f;
9724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9725 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
9727 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9730 ptsize = 1.0f;
9731 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9732 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9733 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
9734 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9736 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
9737 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
9738 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
9739 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
9741 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
9742 ptsize = 15.0f;
9743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9744 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9745 ptsize = 1.0f;
9746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
9747 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
9749 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
9752 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9754 /* pointsize < pointsize_min < pointsize_max?
9755 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
9756 ptsize = 1.0f;
9757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
9758 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9759 ptsize = 15.0f;
9760 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
9761 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
9763 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
9766 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
9768 hr = IDirect3DDevice9_EndScene(device);
9769 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9771 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
9772 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
9773 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
9775 if (caps.MaxPointSize >= 63.0)
9777 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9778 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9781 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9782 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9783 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9784 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9785 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9787 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9789 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9790 * generates texture coordinates for the point(result: Yes, it does)
9792 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9793 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9794 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9797 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9799 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9800 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9801 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9802 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9803 memset(&lr, 0, sizeof(lr));
9804 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9805 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9806 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9807 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9808 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9809 memset(&lr, 0, sizeof(lr));
9810 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9811 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9812 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9813 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9814 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9815 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9816 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9817 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9818 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9819 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9820 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9821 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9822 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9823 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9824 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9825 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9826 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9827 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9828 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9831 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9832 ptsize = 32.0;
9833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9834 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9836 hr = IDirect3DDevice9_BeginScene(device);
9837 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9839 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9840 hr = IDirect3DDevice9_EndScene(device);
9841 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9843 color = getPixelColor(device, 64-4, 64-4);
9844 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9845 color = getPixelColor(device, 64-4, 64+4);
9846 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9847 color = getPixelColor(device, 64+4, 64+4);
9848 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9849 color = getPixelColor(device, 64+4, 64-4);
9850 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9851 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9853 U(matrix).m[0][0] = 1.0f / 64.0f;
9854 U(matrix).m[1][1] = -1.0f / 64.0f;
9855 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9856 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9858 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9859 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9861 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9862 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9863 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9865 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9866 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
9868 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9870 hr = IDirect3DDevice9_BeginScene(device);
9871 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9873 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9874 hr = IDirect3DDevice9_EndScene(device);
9875 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9877 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9878 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9879 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9880 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9881 IDirect3DSurface9_Release(backbuffer);
9882 IDirect3DSurface9_Release(rt);
9884 color = getPixelColor(device, 64-4, 64-4);
9885 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9886 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9887 color = getPixelColor(device, 64+4, 64-4);
9888 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9889 "Expected color 0x00ffff00, got 0x%08x.\n", color);
9890 color = getPixelColor(device, 64-4, 64+4);
9891 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9892 "Expected color 0x00000000, got 0x%08x.\n", color);
9893 color = getPixelColor(device, 64+4, 64+4);
9894 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9895 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9897 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9898 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9900 IDirect3DTexture9_Release(tex1);
9901 IDirect3DTexture9_Release(tex2);
9902 refcount = IDirect3DDevice9_Release(device);
9903 ok(!refcount, "Device has %u references left.\n", refcount);
9904 done:
9905 IDirect3D9_Release(d3d);
9906 DestroyWindow(window);
9909 static void multiple_rendertargets_test(void)
9911 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9912 IDirect3DPixelShader9 *ps1, *ps2;
9913 IDirect3DTexture9 *tex1, *tex2;
9914 IDirect3DVertexShader9 *vs;
9915 IDirect3DDevice9 *device;
9916 IDirect3D9 *d3d;
9917 ULONG refcount;
9918 D3DCAPS9 caps;
9919 DWORD color;
9920 HWND window;
9921 HRESULT hr;
9922 UINT i, j;
9924 static const DWORD vshader_code[] =
9926 0xfffe0300, /* vs_3_0 */
9927 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9928 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9929 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9930 0x0000ffff /* end */
9932 static const DWORD pshader_code1[] =
9934 0xffff0300, /* ps_3_0 */
9935 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9936 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9937 0x0000ffff /* end */
9939 static const DWORD pshader_code2[] =
9941 0xffff0300, /* ps_3_0 */
9942 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9943 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9944 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9945 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9946 0x0000ffff /* end */
9948 static const float quad[] =
9950 -1.0f, -1.0f, 0.1f,
9951 -1.0f, 1.0f, 0.1f,
9952 1.0f, -1.0f, 0.1f,
9953 1.0f, 1.0f, 0.1f,
9955 static const float texquad[] =
9957 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9958 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9959 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9960 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9962 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9963 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9964 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9965 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9968 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9969 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9970 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9971 ok(!!d3d, "Failed to create a D3D object.\n");
9972 if (!(device = create_device(d3d, window, window, TRUE)))
9974 skip("Failed to create a D3D device, skipping tests.\n");
9975 goto done;
9978 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9979 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9980 if (caps.NumSimultaneousRTs < 2)
9982 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
9983 IDirect3DDevice9_Release(device);
9984 goto done;
9986 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9988 skip("No shader model 3 support, skipping tests.\n");
9989 IDirect3DDevice9_Release(device);
9990 goto done;
9993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
9994 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9996 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9997 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9998 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
10000 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10001 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
10002 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10003 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10004 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
10005 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10006 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
10007 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
10008 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
10009 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10010 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
10011 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10013 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
10014 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
10015 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
10016 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10017 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
10018 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10020 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10021 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10022 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
10023 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10024 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
10025 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10026 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10027 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10029 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10030 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10031 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10032 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10033 color = getPixelColorFromSurface(readback, 8, 8);
10034 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10035 "Expected color 0x000000ff, got 0x%08x.\n", color);
10036 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10037 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10038 color = getPixelColorFromSurface(readback, 8, 8);
10039 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10040 "Expected color 0x000000ff, got 0x%08x.\n", color);
10042 /* Render targets not written by the pixel shader should be unmodified. */
10043 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
10044 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10045 hr = IDirect3DDevice9_BeginScene(device);
10046 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10048 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10049 hr = IDirect3DDevice9_EndScene(device);
10050 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10051 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10052 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10053 color = getPixelColorFromSurface(readback, 8, 8);
10054 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10055 "Expected color 0xff00ff00, got 0x%08x.\n", color);
10056 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10057 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10058 for (i = 6; i < 10; ++i)
10060 for (j = 6; j < 10; ++j)
10062 color = getPixelColorFromSurface(readback, j, i);
10063 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10064 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
10068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
10069 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10070 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10071 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10072 color = getPixelColorFromSurface(readback, 8, 8);
10073 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10074 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10075 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10076 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10077 color = getPixelColorFromSurface(readback, 8, 8);
10078 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10079 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10081 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
10082 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10084 hr = IDirect3DDevice9_BeginScene(device);
10085 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10088 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10091 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10092 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10093 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10094 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10095 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10096 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
10097 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10098 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
10099 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10100 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10101 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10103 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10104 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
10106 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10108 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
10109 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10110 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
10111 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10113 hr = IDirect3DDevice9_EndScene(device);
10114 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10116 color = getPixelColor(device, 160, 240);
10117 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
10118 color = getPixelColor(device, 480, 240);
10119 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
10120 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10122 IDirect3DPixelShader9_Release(ps2);
10123 IDirect3DPixelShader9_Release(ps1);
10124 IDirect3DVertexShader9_Release(vs);
10125 IDirect3DTexture9_Release(tex1);
10126 IDirect3DTexture9_Release(tex2);
10127 IDirect3DSurface9_Release(surf1);
10128 IDirect3DSurface9_Release(surf2);
10129 IDirect3DSurface9_Release(backbuf);
10130 IDirect3DSurface9_Release(readback);
10131 refcount = IDirect3DDevice9_Release(device);
10132 ok(!refcount, "Device has %u references left.\n", refcount);
10133 done:
10134 IDirect3D9_Release(d3d);
10135 DestroyWindow(window);
10138 static void pixelshader_blending_test(void)
10140 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
10141 IDirect3DTexture9 *offscreenTexture = NULL;
10142 IDirect3DDevice9 *device;
10143 IDirect3D9 *d3d;
10144 ULONG refcount;
10145 int fmt_index;
10146 DWORD color;
10147 HWND window;
10148 HRESULT hr;
10150 static const struct
10152 const char *fmtName;
10153 D3DFORMAT textureFormat;
10154 D3DCOLOR resultColorBlending;
10155 D3DCOLOR resultColorNoBlending;
10157 test_formats[] =
10159 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
10160 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
10161 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff},
10162 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000},
10163 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
10164 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff},
10165 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000},
10167 static const float quad[][5] =
10169 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
10170 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
10171 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
10172 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
10174 static const struct
10176 struct vec3 position;
10177 DWORD diffuse;
10179 /* Quad with R=0x10, G=0x20 */
10180 quad1[] =
10182 {{-1.0f, -1.0f, 0.1f}, 0x80102000},
10183 {{-1.0f, 1.0f, 0.1f}, 0x80102000},
10184 {{ 1.0f, -1.0f, 0.1f}, 0x80102000},
10185 {{ 1.0f, 1.0f, 0.1f}, 0x80102000},
10187 /* Quad with R=0x20, G=0x10 */
10188 quad2[] =
10190 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
10191 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
10192 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
10193 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
10196 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10197 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10198 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10199 ok(!!d3d, "Failed to create a D3D object.\n");
10200 if (!(device = create_device(d3d, window, window, TRUE)))
10202 skip("Failed to create a D3D device, skipping tests.\n");
10203 goto done;
10206 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10207 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
10209 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
10211 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
10213 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10214 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
10216 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
10217 continue;
10220 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10221 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
10223 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
10224 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
10225 if(!offscreenTexture) {
10226 continue;
10229 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
10230 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
10231 if(!offscreen) {
10232 continue;
10235 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10236 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
10238 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10239 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10240 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10241 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10243 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
10244 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10245 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
10246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10247 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10249 /* Below we will draw two quads with different colors and try to blend
10250 * them together. The result color is compared with the expected
10251 * outcome. */
10252 hr = IDirect3DDevice9_BeginScene(device);
10253 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10255 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
10256 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
10258 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
10261 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10263 /* Draw a quad using color 0x0010200. */
10264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
10265 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
10267 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10269 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10271 /* Draw a quad using color 0x0020100. */
10272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
10273 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
10275 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10277 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10279 /* We don't want to blend the result on the backbuffer. */
10280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
10281 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10283 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
10284 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10285 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10286 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
10287 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
10289 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10290 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10292 /* This time with the texture. */
10293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10294 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10296 hr = IDirect3DDevice9_EndScene(device);
10297 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10299 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10300 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
10302 /* Compare the color of the center quad with our expectation. */
10303 color = getPixelColor(device, 320, 240);
10304 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
10305 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
10306 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
10308 else
10310 /* No pixel shader blending is supported so expect garbage. The
10311 * type of 'garbage' depends on the driver version and OS. E.g. on
10312 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
10313 * modern ones 0x002010ff which is also what NVIDIA reports. On
10314 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
10315 color = getPixelColor(device, 320, 240);
10316 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
10317 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
10318 test_formats[fmt_index].fmtName, color);
10320 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10322 IDirect3DDevice9_SetTexture(device, 0, NULL);
10323 if(offscreenTexture) {
10324 IDirect3DTexture9_Release(offscreenTexture);
10326 if(offscreen) {
10327 IDirect3DSurface9_Release(offscreen);
10331 IDirect3DSurface9_Release(backbuffer);
10332 refcount = IDirect3DDevice9_Release(device);
10333 ok(!refcount, "Device has %u references left.\n", refcount);
10334 done:
10335 IDirect3D9_Release(d3d);
10336 DestroyWindow(window);
10339 static void tssargtemp_test(void)
10341 IDirect3DDevice9 *device;
10342 IDirect3D9 *d3d;
10343 D3DCOLOR color;
10344 ULONG refcount;
10345 D3DCAPS9 caps;
10346 HWND window;
10347 HRESULT hr;
10349 static const struct
10351 struct vec3 position;
10352 DWORD diffuse;
10354 quad[] =
10356 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
10357 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
10358 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
10359 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
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 with %08x\n", hr);
10375 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
10376 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
10377 IDirect3DDevice9_Release(device);
10378 goto done;
10381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
10382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10384 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10385 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10386 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10387 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10389 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10390 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10391 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
10392 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10393 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
10394 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10396 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
10397 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10398 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
10399 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10400 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
10401 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10403 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
10404 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10406 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
10407 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10409 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10410 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10411 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10413 hr = IDirect3DDevice9_BeginScene(device);
10414 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10416 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10417 hr = IDirect3DDevice9_EndScene(device);
10418 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10420 color = getPixelColor(device, 320, 240);
10421 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
10422 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10424 refcount = IDirect3DDevice9_Release(device);
10425 ok(!refcount, "Device has %u references left.\n", refcount);
10426 done:
10427 IDirect3D9_Release(d3d);
10428 DestroyWindow(window);
10431 /* Drawing Indexed Geometry with instances*/
10432 static void stream_test(void)
10434 IDirect3DVertexDeclaration9 *pDecl = NULL;
10435 IDirect3DVertexShader9 *shader = NULL;
10436 IDirect3DVertexBuffer9 *vb3 = NULL;
10437 IDirect3DVertexBuffer9 *vb2 = NULL;
10438 IDirect3DVertexBuffer9 *vb = NULL;
10439 IDirect3DIndexBuffer9 *ib = NULL;
10440 IDirect3DDevice9 *device;
10441 IDirect3D9 *d3d;
10442 ULONG refcount;
10443 D3DCAPS9 caps;
10444 DWORD color;
10445 HWND window;
10446 unsigned i;
10447 HRESULT hr;
10448 BYTE *data;
10449 DWORD ind;
10451 static const struct testdata
10453 DWORD idxVertex; /* number of instances in the first stream */
10454 DWORD idxColor; /* number of instances in the second stream */
10455 DWORD idxInstance; /* should be 1 ?? */
10456 DWORD color1; /* color 1 instance */
10457 DWORD color2; /* color 2 instance */
10458 DWORD color3; /* color 3 instance */
10459 DWORD color4; /* color 4 instance */
10460 WORD strVertex; /* specify which stream to use 0-2*/
10461 WORD strColor;
10462 WORD strInstance;
10464 testcases[]=
10466 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
10467 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
10468 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
10469 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
10470 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
10471 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
10472 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
10473 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
10474 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
10475 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
10476 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
10477 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
10478 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
10479 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
10480 #if 0
10481 /* This draws one instance on some machines, no instance on others. */
10482 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
10483 /* This case is handled in a stand alone test,
10484 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
10485 * return D3DERR_INVALIDCALL. */
10486 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
10487 #endif
10489 static const DWORD shader_code[] =
10491 0xfffe0101, /* vs_1_1 */
10492 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10493 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
10494 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
10495 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10496 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
10497 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
10498 0x0000ffff
10500 static const float quad[][3] =
10502 {-0.5f, -0.5f, 1.1f}, /*0 */
10503 {-0.5f, 0.5f, 1.1f}, /*1 */
10504 { 0.5f, -0.5f, 1.1f}, /*2 */
10505 { 0.5f, 0.5f, 1.1f}, /*3 */
10507 static const float vertcolor[][4] =
10509 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
10510 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
10511 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
10512 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
10514 /* 4 position for 4 instances */
10515 static const float instancepos[][3] =
10517 {-0.6f,-0.6f, 0.0f},
10518 { 0.6f,-0.6f, 0.0f},
10519 { 0.6f, 0.6f, 0.0f},
10520 {-0.6f, 0.6f, 0.0f},
10522 static const short indices[] = {0, 1, 2, 2, 1, 3};
10523 D3DVERTEXELEMENT9 decl[] =
10525 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10526 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10527 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10528 D3DDECL_END()
10531 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10532 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10533 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10534 ok(!!d3d, "Failed to create a D3D object.\n");
10535 if (!(device = create_device(d3d, window, window, TRUE)))
10537 skip("Failed to create a D3D device, skipping tests.\n");
10538 goto done;
10541 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10542 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10543 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10545 skip("No vs_3_0 support, skipping tests.\n");
10546 IDirect3DDevice9_Release(device);
10547 goto done;
10550 /* set the default value because it isn't done in wine? */
10551 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10552 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10554 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
10555 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
10556 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10558 /* check wrong cases */
10559 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
10560 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10561 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10562 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10563 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
10564 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10565 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10566 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10567 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
10568 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10569 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10570 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10571 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
10572 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10573 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10574 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10575 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
10576 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10577 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10578 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10580 /* set the default value back */
10581 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10582 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10584 /* create all VertexBuffers*/
10585 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
10586 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10587 if(!vb) {
10588 skip("Failed to create a vertex buffer\n");
10589 IDirect3DDevice9_Release(device);
10590 goto done;
10592 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
10593 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10594 if(!vb2) {
10595 skip("Failed to create a vertex buffer\n");
10596 goto out;
10598 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
10599 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10600 if(!vb3) {
10601 skip("Failed to create a vertex buffer\n");
10602 goto out;
10605 /* create IndexBuffer*/
10606 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
10607 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
10608 if(!ib) {
10609 skip("Failed to create an index buffer\n");
10610 goto out;
10613 /* copy all Buffers (Vertex + Index)*/
10614 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
10615 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10616 memcpy(data, quad, sizeof(quad));
10617 hr = IDirect3DVertexBuffer9_Unlock(vb);
10618 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10619 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
10620 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10621 memcpy(data, vertcolor, sizeof(vertcolor));
10622 hr = IDirect3DVertexBuffer9_Unlock(vb2);
10623 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10624 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
10625 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10626 memcpy(data, instancepos, sizeof(instancepos));
10627 hr = IDirect3DVertexBuffer9_Unlock(vb3);
10628 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10629 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
10630 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
10631 memcpy(data, indices, sizeof(indices));
10632 hr = IDirect3DIndexBuffer9_Unlock(ib);
10633 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
10635 /* create VertexShader */
10636 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10637 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10638 if(!shader) {
10639 skip("Failed to create a vetex shader\n");
10640 goto out;
10643 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10644 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10646 hr = IDirect3DDevice9_SetIndices(device, ib);
10647 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
10649 /* run all tests */
10650 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
10652 struct testdata act = testcases[i];
10653 decl[0].Stream = act.strVertex;
10654 decl[1].Stream = act.strColor;
10655 decl[2].Stream = act.strInstance;
10656 /* create VertexDeclarations */
10657 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
10658 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
10660 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10661 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
10663 hr = IDirect3DDevice9_BeginScene(device);
10664 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10666 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
10667 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
10669 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
10670 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
10671 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
10672 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
10673 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10675 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
10676 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
10677 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
10678 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
10679 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10681 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
10682 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
10683 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
10684 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
10685 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10687 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
10688 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10689 hr = IDirect3DDevice9_EndScene(device);
10690 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10692 /* set all StreamSource && StreamSourceFreq back to default */
10693 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
10694 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
10695 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
10696 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10697 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
10698 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
10699 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
10700 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10701 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
10702 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
10703 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
10704 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10706 hr = IDirect3DVertexDeclaration9_Release(pDecl);
10707 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
10709 color = getPixelColor(device, 160, 360);
10710 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
10711 color = getPixelColor(device, 480, 360);
10712 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
10713 color = getPixelColor(device, 480, 120);
10714 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
10715 color = getPixelColor(device, 160, 120);
10716 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
10718 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10719 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
10722 out:
10723 if(vb) IDirect3DVertexBuffer9_Release(vb);
10724 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
10725 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
10726 if(ib)IDirect3DIndexBuffer9_Release(ib);
10727 if(shader)IDirect3DVertexShader9_Release(shader);
10728 refcount = IDirect3DDevice9_Release(device);
10729 ok(!refcount, "Device has %u references left.\n", refcount);
10730 done:
10731 IDirect3D9_Release(d3d);
10732 DestroyWindow(window);
10735 static void np2_stretch_rect_test(void)
10737 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
10738 IDirect3DTexture9 *dsttex = NULL;
10739 IDirect3DDevice9 *device;
10740 IDirect3D9 *d3d;
10741 D3DCOLOR color;
10742 ULONG refcount;
10743 HWND window;
10744 HRESULT hr;
10746 static const D3DRECT r1 = {0, 0, 50, 50 };
10747 static const D3DRECT r2 = {50, 0, 100, 50 };
10748 static const D3DRECT r3 = {50, 50, 100, 100};
10749 static const D3DRECT r4 = {0, 50, 50, 100};
10750 static const float quad[] =
10752 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10753 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10754 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10755 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10758 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10759 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10760 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10761 ok(!!d3d, "Failed to create a D3D object.\n");
10762 if (!(device = create_device(d3d, window, window, TRUE)))
10764 skip("Failed to create a D3D device, skipping tests.\n");
10765 goto done;
10768 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10769 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
10771 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
10772 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
10773 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
10774 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
10776 if(!src || !dsttex) {
10777 skip("One or more test resources could not be created\n");
10778 goto cleanup;
10781 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
10782 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
10784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10785 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10787 /* Clear the StretchRect destination for debugging */
10788 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
10789 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10790 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
10791 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10793 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
10794 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10796 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10797 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10798 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
10799 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10800 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10801 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10802 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
10803 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10805 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
10806 * the target -> texture GL blit path
10808 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
10809 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
10810 IDirect3DSurface9_Release(dst);
10812 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10813 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10815 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
10816 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10817 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10818 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10819 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10820 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10821 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10822 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10824 hr = IDirect3DDevice9_BeginScene(device);
10825 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10826 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10827 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10828 hr = IDirect3DDevice9_EndScene(device);
10829 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10831 color = getPixelColor(device, 160, 360);
10832 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
10833 color = getPixelColor(device, 480, 360);
10834 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
10835 color = getPixelColor(device, 480, 120);
10836 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
10837 color = getPixelColor(device, 160, 120);
10838 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
10839 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10840 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10842 cleanup:
10843 if(src) IDirect3DSurface9_Release(src);
10844 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
10845 if(dsttex) IDirect3DTexture9_Release(dsttex);
10846 refcount = IDirect3DDevice9_Release(device);
10847 ok(!refcount, "Device has %u references left.\n", refcount);
10848 done:
10849 IDirect3D9_Release(d3d);
10850 DestroyWindow(window);
10853 static void texop_test(void)
10855 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10856 IDirect3DTexture9 *texture = NULL;
10857 D3DLOCKED_RECT locked_rect;
10858 IDirect3DDevice9 *device;
10859 IDirect3D9 *d3d;
10860 D3DCOLOR color;
10861 ULONG refcount;
10862 D3DCAPS9 caps;
10863 HWND window;
10864 HRESULT hr;
10865 unsigned i;
10867 static const struct {
10868 float x, y, z;
10869 float s, t;
10870 D3DCOLOR diffuse;
10871 } quad[] = {
10872 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10873 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10874 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10875 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10878 static const D3DVERTEXELEMENT9 decl_elements[] = {
10879 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10880 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10881 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10882 D3DDECL_END()
10885 static const struct {
10886 D3DTEXTUREOP op;
10887 const char *name;
10888 DWORD caps_flag;
10889 D3DCOLOR result;
10890 } test_data[] = {
10891 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10892 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10893 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10894 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10895 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10896 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10897 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10898 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10899 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10900 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10901 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10902 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10903 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10904 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10905 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10906 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10907 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10908 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10909 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10910 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10911 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10912 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10913 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10916 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10917 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10918 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10919 ok(!!d3d, "Failed to create a D3D object.\n");
10920 if (!(device = create_device(d3d, window, window, TRUE)))
10922 skip("Failed to create a D3D device, skipping tests.\n");
10923 goto done;
10926 memset(&caps, 0, sizeof(caps));
10927 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10928 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10930 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10931 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10932 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10933 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10935 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10936 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10937 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10938 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10939 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10940 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10941 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10942 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10943 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10945 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10946 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10947 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10948 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10949 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10950 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10952 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10953 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10956 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10958 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10960 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10963 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10965 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10967 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10969 skip("tex operation %s not supported\n", test_data[i].name);
10970 continue;
10973 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10974 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10976 hr = IDirect3DDevice9_BeginScene(device);
10977 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10980 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10982 hr = IDirect3DDevice9_EndScene(device);
10983 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10985 color = getPixelColor(device, 320, 240);
10986 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10987 test_data[i].name, color, test_data[i].result);
10989 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10990 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10993 IDirect3DTexture9_Release(texture);
10994 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10995 refcount = IDirect3DDevice9_Release(device);
10996 ok(!refcount, "Device has %u references left.\n", refcount);
10997 done:
10998 IDirect3D9_Release(d3d);
10999 DestroyWindow(window);
11002 static void yuv_color_test(void)
11004 HRESULT hr;
11005 IDirect3DSurface9 *surface, *target;
11006 unsigned int i;
11007 D3DLOCKED_RECT lr;
11008 IDirect3D9 *d3d;
11009 D3DCOLOR color;
11010 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
11011 IDirect3DDevice9 *device;
11012 D3DSURFACE_DESC desc;
11013 ULONG refcount;
11014 HWND window;
11016 static const struct
11018 DWORD in;
11019 D3DFORMAT format;
11020 const char *fmt_string;
11021 D3DCOLOR left, right;
11023 test_data[] =
11025 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
11026 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
11027 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
11028 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
11029 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
11030 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
11031 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
11032 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
11033 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
11034 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
11035 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
11036 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
11037 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
11038 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
11039 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
11040 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
11041 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
11042 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
11044 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
11045 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
11046 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
11047 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
11048 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
11049 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
11050 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
11051 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
11052 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
11053 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
11054 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
11055 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
11056 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
11057 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
11058 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
11059 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
11060 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
11061 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
11064 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11065 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11066 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11067 ok(!!d3d, "Failed to create a D3D object.\n");
11068 if (!(device = create_device(d3d, window, window, TRUE)))
11070 skip("Failed to create a D3D device, skipping tests.\n");
11071 goto done;
11074 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11075 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
11076 hr = IDirect3DSurface9_GetDesc(target, &desc);
11077 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11079 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11081 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
11082 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
11083 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11084 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
11086 if (skip_once != test_data[i].format)
11088 skip("%s is not supported.\n", test_data[i].fmt_string);
11089 skip_once = test_data[i].format;
11091 continue;
11093 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11094 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
11096 if (skip_once != test_data[i].format)
11098 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
11099 skip_once = test_data[i].format;
11101 continue;
11104 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
11105 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
11106 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
11107 * second luminance value, resulting in an incorrect color in the right pixel. */
11108 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
11109 D3DPOOL_DEFAULT, &surface, NULL);
11110 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
11113 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11114 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
11115 ((DWORD *)lr.pBits)[0] = test_data[i].in;
11116 ((DWORD *)lr.pBits)[1] = 0x00800080;
11117 hr = IDirect3DSurface9_UnlockRect(surface);
11118 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
11120 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11121 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11122 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11123 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
11125 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11126 * although we asked for point filtering. Be careful when reading the results and use the pixel
11127 * centers. In the future we may want to add tests for the filtered pixels as well.
11129 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11130 * vastly differently, so we need a max diff of 18. */
11131 color = getPixelColor(device, 1, 240);
11132 ok(color_match(color, test_data[i].left, 18),
11133 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
11134 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
11135 color = getPixelColor(device, 318, 240);
11136 ok(color_match(color, test_data[i].right, 18),
11137 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
11138 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
11139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11140 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11141 IDirect3DSurface9_Release(surface);
11144 IDirect3DSurface9_Release(target);
11145 refcount = IDirect3DDevice9_Release(device);
11146 ok(!refcount, "Device has %u references left.\n", refcount);
11147 done:
11148 IDirect3D9_Release(d3d);
11149 DestroyWindow(window);
11152 static void yuv_layout_test(void)
11154 HRESULT hr;
11155 IDirect3DSurface9 *surface, *target;
11156 unsigned int fmt, i, x, y;
11157 D3DFORMAT format;
11158 const char *fmt_string;
11159 D3DLOCKED_RECT lr;
11160 IDirect3D9 *d3d;
11161 D3DCOLOR color;
11162 DWORD ref_color;
11163 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
11164 UINT width = 20, height = 16;
11165 IDirect3DDevice9 *device;
11166 ULONG refcount;
11167 D3DCAPS9 caps;
11168 D3DSURFACE_DESC desc;
11169 HWND window;
11171 static const struct
11173 DWORD color1, color2;
11174 DWORD rgb1, rgb2;
11176 test_data[] =
11178 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
11179 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
11180 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
11181 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
11182 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
11183 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
11184 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
11185 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
11188 static const struct
11190 D3DFORMAT format;
11191 const char *str;
11193 formats[] =
11195 { D3DFMT_UYVY, "D3DFMT_UYVY", },
11196 { D3DFMT_YUY2, "D3DFMT_YUY2", },
11197 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
11198 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
11201 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11202 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11203 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11204 ok(!!d3d, "Failed to create a D3D object.\n");
11205 if (!(device = create_device(d3d, window, window, TRUE)))
11207 skip("Failed to create a D3D device, skipping tests.\n");
11208 goto done;
11211 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11212 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11213 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
11214 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
11216 skip("No NP2 texture support, skipping YUV texture layout test.\n");
11217 IDirect3DDevice9_Release(device);
11218 goto done;
11221 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11222 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
11223 hr = IDirect3DSurface9_GetDesc(target, &desc);
11224 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11226 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
11228 format = formats[fmt].format;
11229 fmt_string = formats[fmt].str;
11231 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
11232 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
11233 * of drawPrimitive. */
11234 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
11235 D3DRTYPE_SURFACE, format) != D3D_OK)
11237 skip("%s is not supported.\n", fmt_string);
11238 continue;
11240 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11241 D3DDEVTYPE_HAL, format, desc.Format)))
11243 skip("Driver cannot blit %s surfaces.\n", fmt_string);
11244 continue;
11247 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
11248 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
11250 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11252 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11253 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
11254 buf = lr.pBits;
11255 chroma_buf = buf + lr.Pitch * height;
11256 if (format == MAKEFOURCC('Y','V','1','2'))
11258 v_buf = chroma_buf;
11259 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
11261 /* Draw the top left quarter of the screen with color1, the rest with color2 */
11262 for (y = 0; y < height; y++)
11264 for (x = 0; x < width; x += 2)
11266 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
11267 BYTE Y = (color >> 16) & 0xff;
11268 BYTE U = (color >> 8) & 0xff;
11269 BYTE V = (color >> 0) & 0xff;
11270 if (format == D3DFMT_UYVY)
11272 buf[y * lr.Pitch + 2 * x + 0] = U;
11273 buf[y * lr.Pitch + 2 * x + 1] = Y;
11274 buf[y * lr.Pitch + 2 * x + 2] = V;
11275 buf[y * lr.Pitch + 2 * x + 3] = Y;
11277 else if (format == D3DFMT_YUY2)
11279 buf[y * lr.Pitch + 2 * x + 0] = Y;
11280 buf[y * lr.Pitch + 2 * x + 1] = U;
11281 buf[y * lr.Pitch + 2 * x + 2] = Y;
11282 buf[y * lr.Pitch + 2 * x + 3] = V;
11284 else if (format == MAKEFOURCC('Y','V','1','2'))
11286 buf[y * lr.Pitch + x + 0] = Y;
11287 buf[y * lr.Pitch + x + 1] = Y;
11288 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
11289 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
11291 else if (format == MAKEFOURCC('N','V','1','2'))
11293 buf[y * lr.Pitch + x + 0] = Y;
11294 buf[y * lr.Pitch + x + 1] = Y;
11295 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
11296 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
11300 hr = IDirect3DSurface9_UnlockRect(surface);
11301 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
11303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11304 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
11305 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11306 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
11308 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11309 * although we asked for point filtering. To prevent running into precision problems, read at points
11310 * with some margin within each quadrant.
11312 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11313 * vastly differently, so we need a max diff of 18. */
11314 for (y = 0; y < 4; y++)
11316 for (x = 0; x < 4; x++)
11318 UINT xcoord = (1 + 2 * x) * 640 / 8;
11319 UINT ycoord = (1 + 2 * y) * 480 / 8;
11320 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
11321 color = getPixelColor(device, xcoord, ycoord);
11322 ok(color_match(color, ref_color, 18),
11323 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
11324 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
11327 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11329 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
11331 IDirect3DSurface9_Release(surface);
11334 IDirect3DSurface9_Release(target);
11335 refcount = IDirect3DDevice9_Release(device);
11336 ok(!refcount, "Device has %u references left.\n", refcount);
11337 done:
11338 IDirect3D9_Release(d3d);
11339 DestroyWindow(window);
11342 static void texop_range_test(void)
11344 IDirect3DTexture9 *texture;
11345 D3DLOCKED_RECT locked_rect;
11346 IDirect3DDevice9 *device;
11347 IDirect3D9 *d3d;
11348 ULONG refcount;
11349 D3DCAPS9 caps;
11350 DWORD color;
11351 HWND window;
11352 HRESULT hr;
11354 static const struct
11356 float x, y, z;
11357 D3DCOLOR diffuse;
11359 quad[] =
11361 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11362 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11363 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11364 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
11367 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11368 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11369 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11370 ok(!!d3d, "Failed to create a D3D object.\n");
11371 if (!(device = create_device(d3d, window, window, TRUE)))
11373 skip("Failed to create a D3D device, skipping tests.\n");
11374 goto done;
11377 /* We need ADD and SUBTRACT operations */
11378 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11379 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11380 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
11382 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
11383 IDirect3DDevice9_Release(device);
11384 goto done;
11386 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
11388 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
11389 IDirect3DDevice9_Release(device);
11390 goto done;
11393 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11394 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
11395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11396 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11397 /* Stage 1: result = diffuse(=1.0) + diffuse
11398 * stage 2: result = result - tfactor(= 0.5)
11400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11401 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11402 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11403 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11404 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
11405 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11406 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
11407 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11408 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
11409 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11410 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11411 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11412 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
11413 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11416 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
11417 hr = IDirect3DDevice9_BeginScene(device);
11418 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11421 hr = IDirect3DDevice9_EndScene(device);
11422 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11424 color = getPixelColor(device, 320, 240);
11425 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
11426 color);
11427 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11428 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11430 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11431 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11432 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11433 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11434 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
11435 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11436 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11437 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11438 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11440 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
11441 * stage 2: result = result + diffuse(1.0)
11443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11444 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11445 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11446 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11447 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11448 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11449 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
11450 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11451 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
11452 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11453 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
11454 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11455 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
11456 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11458 hr = IDirect3DDevice9_BeginScene(device);
11459 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11461 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11462 hr = IDirect3DDevice9_EndScene(device);
11463 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11465 color = getPixelColor(device, 320, 240);
11466 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
11467 color);
11468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11469 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11471 IDirect3DTexture9_Release(texture);
11472 refcount = IDirect3DDevice9_Release(device);
11473 ok(!refcount, "Device has %u references left.\n", refcount);
11474 done:
11475 IDirect3D9_Release(d3d);
11476 DestroyWindow(window);
11479 static void alphareplicate_test(void)
11481 IDirect3DDevice9 *device;
11482 IDirect3D9 *d3d;
11483 ULONG refcount;
11484 DWORD color;
11485 HWND window;
11486 HRESULT hr;
11488 static const struct
11490 struct vec3 position;
11491 DWORD diffuse;
11493 quad[] =
11495 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
11496 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
11497 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
11498 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
11501 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11502 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11503 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11504 ok(!!d3d, "Failed to create a D3D object.\n");
11505 if (!(device = create_device(d3d, window, window, TRUE)))
11507 skip("Failed to create a D3D device, skipping tests.\n");
11508 goto done;
11511 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11512 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11514 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11515 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11517 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11518 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11519 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
11520 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11522 hr = IDirect3DDevice9_BeginScene(device);
11523 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11525 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11526 hr = IDirect3DDevice9_EndScene(device);
11527 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11529 color = getPixelColor(device, 320, 240);
11530 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
11531 color);
11532 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11533 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
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 dp3_alpha_test(void)
11544 IDirect3DDevice9 *device;
11545 IDirect3D9 *d3d;
11546 ULONG refcount;
11547 D3DCAPS9 caps;
11548 DWORD color;
11549 HWND window;
11550 HRESULT hr;
11552 static const struct
11554 struct vec3 position;
11555 DWORD diffuse;
11557 quad[] =
11559 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
11560 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
11561 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
11562 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
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 memset(&caps, 0, sizeof(caps));
11576 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11577 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11578 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
11580 skip("D3DTOP_DOTPRODUCT3 not supported\n");
11581 IDirect3DDevice9_Release(device);
11582 goto done;
11585 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11586 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11588 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11589 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11591 /* dp3_x4 r0, diffuse_bias, tfactor_bias
11592 * mov r0.a, diffuse.a
11593 * mov r0, r0.a
11595 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
11596 * 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
11597 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
11599 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
11600 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11601 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11602 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11603 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11604 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11605 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
11606 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11607 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
11608 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11609 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11610 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11611 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
11612 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11613 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
11614 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
11616 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11618 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11620 hr = IDirect3DDevice9_BeginScene(device);
11621 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11623 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11624 hr = IDirect3DDevice9_EndScene(device);
11625 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11627 color = getPixelColor(device, 320, 240);
11628 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
11629 color);
11630 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11631 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11633 refcount = IDirect3DDevice9_Release(device);
11634 ok(!refcount, "Device has %u references left.\n", refcount);
11635 done:
11636 IDirect3D9_Release(d3d);
11637 DestroyWindow(window);
11640 static void zwriteenable_test(void)
11642 IDirect3DDevice9 *device;
11643 IDirect3D9 *d3d;
11644 D3DCOLOR color;
11645 ULONG refcount;
11646 HWND window;
11647 HRESULT hr;
11649 static const struct
11651 struct vec3 position;
11652 DWORD diffuse;
11654 quad1[] =
11656 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11657 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11658 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11659 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11661 quad2[] =
11663 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
11664 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
11665 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
11666 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
11669 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11670 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11671 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11672 ok(!!d3d, "Failed to create a D3D object.\n");
11673 if (!(device = create_device(d3d, window, window, TRUE)))
11675 skip("Failed to create a D3D device, skipping tests.\n");
11676 goto done;
11679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
11680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11682 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11683 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11684 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11685 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11687 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11689 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11691 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11693 hr = IDirect3DDevice9_BeginScene(device);
11694 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11695 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
11696 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
11697 * because the z test is disabled. The question is whether the z = 0.1
11698 * values are written into the Z buffer. After the draw, set
11699 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
11700 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
11701 * the values are not written, the z test succeeds(0.9 < 1.0) and the
11702 * green color is written. It turns out that the screen is green, so
11703 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
11704 * buffer. */
11705 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11706 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11708 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11710 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11711 hr = IDirect3DDevice9_EndScene(device);
11712 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11714 color = getPixelColor(device, 320, 240);
11715 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
11716 color);
11717 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11718 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11720 refcount = IDirect3DDevice9_Release(device);
11721 ok(!refcount, "Device has %u references left.\n", refcount);
11722 done:
11723 IDirect3D9_Release(d3d);
11724 DestroyWindow(window);
11727 static void alphatest_test(void)
11729 #define ALPHATEST_PASSED 0x0000ff00
11730 #define ALPHATEST_FAILED 0x00ff0000
11731 IDirect3DDevice9 *device;
11732 unsigned int i, j;
11733 IDirect3D9 *d3d;
11734 D3DCOLOR color;
11735 ULONG refcount;
11736 D3DCAPS9 caps;
11737 HWND window;
11738 HRESULT hr;
11740 static const struct
11742 D3DCMPFUNC func;
11743 D3DCOLOR color_less;
11744 D3DCOLOR color_equal;
11745 D3DCOLOR color_greater;
11747 testdata[] =
11749 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11750 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11751 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11752 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11753 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11754 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11755 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11756 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11758 static const struct
11760 struct vec3 position;
11761 DWORD diffuse;
11763 quad[] =
11765 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11766 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11767 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11768 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11771 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11772 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11773 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11774 ok(!!d3d, "Failed to create a D3D object.\n");
11775 if (!(device = create_device(d3d, window, window, TRUE)))
11777 skip("Failed to create a D3D device, skipping tests.\n");
11778 goto done;
11781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11782 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11785 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
11787 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11789 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11791 for (j = 0; j < 2; ++j)
11793 if (j == 1)
11795 /* Try a pixel shader instead of fixed function. The wined3d code
11796 * may emulate the alpha test either for performance reasons
11797 * (floating point RTs) or to work around driver bugs (GeForce
11798 * 7x00 cards on MacOS). There may be a different codepath for ffp
11799 * and shader in this case, and the test should cover both. */
11800 IDirect3DPixelShader9 *ps;
11801 static const DWORD shader_code[] =
11803 0xffff0101, /* ps_1_1 */
11804 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11805 0x0000ffff /* end */
11807 memset(&caps, 0, sizeof(caps));
11808 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11809 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
11810 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
11811 break;
11814 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
11815 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
11816 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11817 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
11818 IDirect3DPixelShader9_Release(ps);
11821 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
11822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
11823 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11826 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
11828 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11829 hr = IDirect3DDevice9_BeginScene(device);
11830 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11832 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11833 hr = IDirect3DDevice9_EndScene(device);
11834 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11835 color = getPixelColor(device, 320, 240);
11836 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
11837 color, testdata[i].color_less, testdata[i].func);
11838 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11839 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11841 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11842 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
11844 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11845 hr = IDirect3DDevice9_BeginScene(device);
11846 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11848 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11849 hr = IDirect3DDevice9_EndScene(device);
11850 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11851 color = getPixelColor(device, 320, 240);
11852 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
11853 color, testdata[i].color_equal, testdata[i].func);
11854 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11855 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11858 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
11860 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11861 hr = IDirect3DDevice9_BeginScene(device);
11862 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11864 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11865 hr = IDirect3DDevice9_EndScene(device);
11866 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11867 color = getPixelColor(device, 320, 240);
11868 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
11869 color, testdata[i].color_greater, testdata[i].func);
11870 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11871 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11875 refcount = IDirect3DDevice9_Release(device);
11876 ok(!refcount, "Device has %u references left.\n", refcount);
11877 done:
11878 IDirect3D9_Release(d3d);
11879 DestroyWindow(window);
11882 static void sincos_test(void)
11884 IDirect3DVertexShader9 *sin_shader, *cos_shader;
11885 IDirect3DDevice9 *device;
11886 struct vec3 data[1280];
11887 IDirect3D9 *d3d;
11888 unsigned int i;
11889 ULONG refcount;
11890 D3DCAPS9 caps;
11891 HWND window;
11892 HRESULT hr;
11894 static const DWORD sin_shader_code[] =
11896 0xfffe0200, /* vs_2_0 */
11897 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11898 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
11899 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
11900 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
11901 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
11902 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
11903 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
11904 0x0000ffff /* end */
11906 static const DWORD cos_shader_code[] =
11908 0xfffe0200, /* vs_2_0 */
11909 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11910 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
11911 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
11912 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
11913 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
11914 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
11915 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
11916 0x0000ffff /* end */
11918 static const float sincosc1[4] = {D3DSINCOSCONST1};
11919 static const float sincosc2[4] = {D3DSINCOSCONST2};
11921 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11922 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11923 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11924 ok(!!d3d, "Failed to create a D3D object.\n");
11925 if (!(device = create_device(d3d, window, window, TRUE)))
11927 skip("Failed to create a D3D device, skipping tests.\n");
11928 goto done;
11931 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11932 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11933 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11935 skip("No vs_2_0 support, skipping tests.\n");
11936 IDirect3DDevice9_Release(device);
11937 goto done;
11940 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11941 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11943 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
11944 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11945 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
11946 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11948 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11949 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
11950 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
11951 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
11952 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
11954 /* Generate a point from -1 to 1 every 0.5 pixels */
11955 for(i = 0; i < 1280; i++) {
11956 data[i].x = (-640.0 + i) / 640.0;
11957 data[i].y = 0.0;
11958 data[i].z = 0.1;
11961 hr = IDirect3DDevice9_BeginScene(device);
11962 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11964 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
11965 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
11967 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11969 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
11970 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11971 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
11972 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11974 hr = IDirect3DDevice9_EndScene(device);
11975 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11978 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
11979 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
11981 IDirect3DVertexShader9_Release(sin_shader);
11982 IDirect3DVertexShader9_Release(cos_shader);
11983 refcount = IDirect3DDevice9_Release(device);
11984 ok(!refcount, "Device has %u references left.\n", refcount);
11985 done:
11986 IDirect3D9_Release(d3d);
11987 DestroyWindow(window);
11990 static void loop_index_test(void)
11992 IDirect3DVertexShader9 *shader;
11993 IDirect3DDevice9 *device;
11994 IDirect3D9 *d3d;
11995 float values[4];
11996 ULONG refcount;
11997 D3DCAPS9 caps;
11998 DWORD color;
11999 HWND window;
12000 HRESULT hr;
12002 static const DWORD shader_code[] =
12004 0xfffe0200, /* vs_2_0 */
12005 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12006 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
12007 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
12008 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
12009 0x0000001d, /* endloop */
12010 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12011 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
12012 0x0000ffff /* END */
12014 static const float quad[] =
12016 -1.0f, -1.0f, 0.1f,
12017 -1.0f, 1.0f, 0.1f,
12018 1.0f, -1.0f, 0.1f,
12019 1.0f, 1.0f, 0.1f,
12021 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
12022 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
12023 static const int i0[4] = {2, 10, -3, 0};
12025 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12026 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12027 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12028 ok(!!d3d, "Failed to create a D3D object.\n");
12029 if (!(device = create_device(d3d, window, window, TRUE)))
12031 skip("Failed to create a D3D device, skipping tests.\n");
12032 goto done;
12035 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12036 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12037 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12039 skip("No vs_2_0 support, skipping tests.\n");
12040 IDirect3DDevice9_Release(device);
12041 goto done;
12044 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12045 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12046 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12047 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12048 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12049 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12051 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12053 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
12054 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12055 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
12056 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12057 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
12058 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12059 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
12060 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12061 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
12062 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12063 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
12064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12065 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
12066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12067 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
12068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12069 values[0] = 1.0;
12070 values[1] = 1.0;
12071 values[2] = 0.0;
12072 values[3] = 0.0;
12073 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
12074 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12075 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
12076 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12077 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
12078 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12079 values[0] = -1.0;
12080 values[1] = 0.0;
12081 values[2] = 0.0;
12082 values[3] = 0.0;
12083 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
12084 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12085 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
12086 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12087 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
12088 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12089 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
12090 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12091 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
12092 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12094 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
12095 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
12097 hr = IDirect3DDevice9_BeginScene(device);
12098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12100 hr = IDirect3DDevice9_EndScene(device);
12101 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12102 color = getPixelColor(device, 320, 240);
12103 ok(color_match(color, 0x0000ff00, 1),
12104 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
12105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12106 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12108 IDirect3DVertexShader9_Release(shader);
12109 refcount = IDirect3DDevice9_Release(device);
12110 ok(!refcount, "Device has %u references left.\n", refcount);
12111 done:
12112 IDirect3D9_Release(d3d);
12113 DestroyWindow(window);
12116 static void sgn_test(void)
12118 IDirect3DVertexShader9 *shader;
12119 IDirect3DDevice9 *device;
12120 IDirect3D9 *d3d;
12121 ULONG refcount;
12122 D3DCAPS9 caps;
12123 DWORD color;
12124 HWND window;
12125 HRESULT hr;
12127 static const DWORD shader_code[] =
12129 0xfffe0200, /* vs_2_0 */
12130 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
12131 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
12132 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
12133 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12134 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
12135 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
12136 0x0000ffff /* end */
12138 static const float quad[] =
12140 -1.0f, -1.0f, 0.1f,
12141 -1.0f, 1.0f, 0.1f,
12142 1.0f, -1.0f, 0.1f,
12143 1.0f, 1.0f, 0.1f,
12146 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12147 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12148 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12149 ok(!!d3d, "Failed to create a D3D object.\n");
12150 if (!(device = create_device(d3d, window, window, TRUE)))
12152 skip("Failed to create a D3D device, skipping tests.\n");
12153 goto done;
12156 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12157 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12158 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12160 skip("No vs_2_0 support, skipping tests.\n");
12161 IDirect3DDevice9_Release(device);
12162 goto done;
12165 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12167 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12168 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12169 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12170 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12171 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12172 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12174 hr = IDirect3DDevice9_BeginScene(device);
12175 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12177 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12178 hr = IDirect3DDevice9_EndScene(device);
12179 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12180 color = getPixelColor(device, 320, 240);
12181 ok(color_match(color, 0x008000ff, 1),
12182 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
12183 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12184 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12186 IDirect3DVertexShader9_Release(shader);
12187 refcount = IDirect3DDevice9_Release(device);
12188 ok(!refcount, "Device has %u references left.\n", refcount);
12189 done:
12190 IDirect3D9_Release(d3d);
12191 DestroyWindow(window);
12194 static void viewport_test(void)
12196 IDirect3DDevice9 *device;
12197 BOOL draw_failed = TRUE;
12198 D3DVIEWPORT9 vp;
12199 IDirect3D9 *d3d;
12200 ULONG refcount;
12201 DWORD color;
12202 HWND window;
12203 HRESULT hr;
12205 static const float quad[] =
12207 -0.5f, -0.5f, 0.1f,
12208 -0.5f, 0.5f, 0.1f,
12209 0.5f, -0.5f, 0.1f,
12210 0.5f, 0.5f, 0.1f,
12213 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12214 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12215 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12216 ok(!!d3d, "Failed to create a D3D object.\n");
12217 if (!(device = create_device(d3d, window, window, TRUE)))
12219 skip("Failed to create a D3D device, skipping tests.\n");
12220 goto done;
12223 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12224 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12226 /* Test a viewport with Width and Height bigger than the surface dimensions
12228 * TODO: Test Width < surface.width, but X + Width > surface.width
12229 * TODO: Test Width < surface.width, what happens with the height?
12231 * The expected behavior is that the viewport behaves like the "default"
12232 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
12233 * MinZ = 0.0, MaxZ = 1.0.
12235 * Starting with Windows 7 the behavior among driver versions is not
12236 * consistent. The SetViewport call is accepted on all drivers. Some
12237 * drivers(older nvidia ones) refuse to draw and return an error. Newer
12238 * nvidia drivers draw, but use the actual values in the viewport and only
12239 * display the upper left part on the surface.
12241 memset(&vp, 0, sizeof(vp));
12242 vp.X = 0;
12243 vp.Y = 0;
12244 vp.Width = 10000;
12245 vp.Height = 10000;
12246 vp.MinZ = 0.0;
12247 vp.MaxZ = 0.0;
12248 hr = IDirect3DDevice9_SetViewport(device, &vp);
12249 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
12251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12252 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12254 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12255 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
12256 hr = IDirect3DDevice9_BeginScene(device);
12257 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12259 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
12260 draw_failed = FAILED(hr);
12261 hr = IDirect3DDevice9_EndScene(device);
12262 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12264 if(!draw_failed)
12266 color = getPixelColor(device, 158, 118);
12267 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
12268 color = getPixelColor(device, 162, 118);
12269 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
12270 color = getPixelColor(device, 158, 122);
12271 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
12272 color = getPixelColor(device, 162, 122);
12273 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
12275 color = getPixelColor(device, 478, 358);
12276 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
12277 color = getPixelColor(device, 482, 358);
12278 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
12279 color = getPixelColor(device, 478, 362);
12280 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
12281 color = getPixelColor(device, 482, 362);
12282 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
12285 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12286 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12288 refcount = IDirect3DDevice9_Release(device);
12289 ok(!refcount, "Device has %u references left.\n", refcount);
12290 done:
12291 IDirect3D9_Release(d3d);
12292 DestroyWindow(window);
12295 /* This test tests depth clamping / clipping behaviour:
12296 * - With software vertex processing, depth values are clamped to the
12297 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
12298 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
12299 * same as regular vertices here.
12300 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
12301 * Normal vertices are always clipped. Pretransformed vertices are
12302 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
12303 * - The viewport's MinZ/MaxZ is irrelevant for this.
12305 static void depth_clamp_test(void)
12307 IDirect3DDevice9 *device;
12308 D3DVIEWPORT9 vp;
12309 IDirect3D9 *d3d;
12310 D3DCOLOR color;
12311 ULONG refcount;
12312 D3DCAPS9 caps;
12313 HWND window;
12314 HRESULT hr;
12316 static const struct
12318 struct vec4 position;
12319 DWORD diffuse;
12321 quad1[] =
12323 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
12324 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
12325 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
12326 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
12328 quad2[] =
12330 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
12331 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
12332 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
12333 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
12335 quad3[] =
12337 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
12338 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
12339 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
12340 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
12342 quad4[] =
12344 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
12345 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
12346 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
12347 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
12349 static const struct
12351 struct vec3 position;
12352 DWORD diffuse;
12354 quad5[] =
12356 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
12357 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
12358 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
12359 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
12361 quad6[] =
12363 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
12364 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
12365 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
12366 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
12369 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12370 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12371 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12372 ok(!!d3d, "Failed to create a D3D object.\n");
12373 if (!(device = create_device(d3d, window, window, TRUE)))
12375 skip("Failed to create a D3D device, skipping tests.\n");
12376 goto done;
12379 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12380 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12382 vp.X = 0;
12383 vp.Y = 0;
12384 vp.Width = 640;
12385 vp.Height = 480;
12386 vp.MinZ = 0.0;
12387 vp.MaxZ = 7.5;
12389 hr = IDirect3DDevice9_SetViewport(device, &vp);
12390 if(FAILED(hr))
12392 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
12393 * the tests because the 7.5 is just intended to show that it doesn't have
12394 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
12395 * viewport and continue.
12397 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
12398 vp.MaxZ = 1.0;
12399 hr = IDirect3DDevice9_SetViewport(device, &vp);
12401 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12403 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
12404 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12406 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
12407 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12409 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12411 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12413 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12415 hr = IDirect3DDevice9_BeginScene(device);
12416 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12418 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
12419 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12422 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12424 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12427 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12430 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12431 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
12432 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
12435 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12437 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12438 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
12441 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12444 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
12447 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12449 hr = IDirect3DDevice9_EndScene(device);
12450 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12452 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
12454 color = getPixelColor(device, 75, 75);
12455 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12456 color = getPixelColor(device, 150, 150);
12457 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12458 color = getPixelColor(device, 320, 240);
12459 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12460 color = getPixelColor(device, 320, 330);
12461 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12462 color = getPixelColor(device, 320, 330);
12463 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12465 else
12467 color = getPixelColor(device, 75, 75);
12468 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
12469 color = getPixelColor(device, 150, 150);
12470 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
12471 color = getPixelColor(device, 320, 240);
12472 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
12473 color = getPixelColor(device, 320, 330);
12474 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12475 color = getPixelColor(device, 320, 330);
12476 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12479 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12480 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12482 refcount = IDirect3DDevice9_Release(device);
12483 ok(!refcount, "Device has %u references left.\n", refcount);
12484 done:
12485 IDirect3D9_Release(d3d);
12486 DestroyWindow(window);
12489 static void depth_bounds_test(void)
12491 static const struct
12493 struct vec4 position;
12494 DWORD diffuse;
12496 quad1[] =
12498 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
12499 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
12500 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
12501 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
12503 quad2[] =
12505 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
12506 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
12507 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
12508 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
12510 quad3[] =
12512 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
12513 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
12514 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
12515 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
12518 union {
12519 DWORD d;
12520 float f;
12521 } tmpvalue;
12523 IDirect3DSurface9 *offscreen_surface = NULL;
12524 IDirect3DDevice9 *device;
12525 IDirect3D9 *d3d;
12526 D3DCOLOR color;
12527 ULONG refcount;
12528 HWND window;
12529 HRESULT hr;
12531 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12532 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12533 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12534 ok(!!d3d, "Failed to create a D3D object.\n");
12535 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12536 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
12538 skip("No NVDB (depth bounds test) support, skipping tests.\n");
12539 goto done;
12541 if (!(device = create_device(d3d, window, window, TRUE)))
12543 skip("Failed to create a D3D device, skipping tests.\n");
12544 goto done;
12547 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
12548 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
12549 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
12550 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
12552 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
12553 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12556 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12557 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
12558 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12560 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12562 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12565 hr = IDirect3DDevice9_BeginScene(device);
12566 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12568 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
12569 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12572 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
12575 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12577 tmpvalue.f = 0.625;
12578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
12579 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12581 tmpvalue.f = 0.75;
12582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
12583 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12586 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12588 tmpvalue.f = 0.75;
12589 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
12590 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12593 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
12596 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12598 hr = IDirect3DDevice9_EndScene(device);
12599 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12601 color = getPixelColor(device, 150, 130);
12602 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12603 color = getPixelColor(device, 150, 200);
12604 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12605 color = getPixelColor(device, 150, 300-5);
12606 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12607 color = getPixelColor(device, 150, 300+5);
12608 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
12609 color = getPixelColor(device, 150, 330);
12610 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
12611 color = getPixelColor(device, 150, 360-5);
12612 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
12613 color = getPixelColor(device, 150, 360+5);
12614 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12616 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12617 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12618 refcount = IDirect3DDevice9_Release(device);
12619 ok(!refcount, "Device has %u references left.\n", refcount);
12620 done:
12621 IDirect3D9_Release(d3d);
12622 DestroyWindow(window);
12625 static void depth_buffer_test(void)
12627 static const struct
12629 struct vec3 position;
12630 DWORD diffuse;
12632 quad1[] =
12634 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
12635 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
12636 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
12637 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
12639 quad2[] =
12641 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
12642 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
12643 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
12644 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
12646 quad3[] =
12648 {{-1.0, 1.0, 0.66f}, 0xffff0000},
12649 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
12650 {{-1.0, -1.0, 0.66f}, 0xffff0000},
12651 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
12653 static const DWORD expected_colors[4][4] =
12655 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12656 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12657 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
12658 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12661 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
12662 IDirect3DDevice9 *device;
12663 unsigned int i, j;
12664 D3DVIEWPORT9 vp;
12665 IDirect3D9 *d3d;
12666 D3DCOLOR color;
12667 ULONG refcount;
12668 HWND window;
12669 HRESULT hr;
12671 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12672 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12673 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12674 ok(!!d3d, "Failed to create a D3D object.\n");
12675 if (!(device = create_device(d3d, window, window, TRUE)))
12677 skip("Failed to create a D3D device, skipping tests.\n");
12678 goto done;
12681 vp.X = 0;
12682 vp.Y = 0;
12683 vp.Width = 640;
12684 vp.Height = 480;
12685 vp.MinZ = 0.0;
12686 vp.MaxZ = 1.0;
12688 hr = IDirect3DDevice9_SetViewport(device, &vp);
12689 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12692 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12693 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12694 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12696 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12698 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12699 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12700 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12702 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12703 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12704 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
12705 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
12706 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12707 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
12708 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
12709 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12710 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12711 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
12712 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12714 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
12715 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
12717 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12719 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12720 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12721 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12722 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12724 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
12725 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12726 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
12727 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12729 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
12730 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12731 hr = IDirect3DDevice9_BeginScene(device);
12732 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12733 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12734 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12735 hr = IDirect3DDevice9_EndScene(device);
12736 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12738 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12739 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12742 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12744 hr = IDirect3DDevice9_BeginScene(device);
12745 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12747 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12749 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12750 hr = IDirect3DDevice9_EndScene(device);
12751 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12753 for (i = 0; i < 4; ++i)
12755 for (j = 0; j < 4; ++j)
12757 unsigned int x = 80 * ((2 * j) + 1);
12758 unsigned int y = 60 * ((2 * i) + 1);
12759 color = getPixelColor(device, x, y);
12760 ok(color_match(color, expected_colors[i][j], 0),
12761 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
12765 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12766 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12768 IDirect3DSurface9_Release(backbuffer);
12769 IDirect3DSurface9_Release(rt3);
12770 IDirect3DSurface9_Release(rt2);
12771 IDirect3DSurface9_Release(rt1);
12772 refcount = IDirect3DDevice9_Release(device);
12773 ok(!refcount, "Device has %u references left.\n", refcount);
12774 done:
12775 IDirect3D9_Release(d3d);
12776 DestroyWindow(window);
12779 /* Test that partial depth copies work the way they're supposed to. The clear
12780 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
12781 * the following draw should only copy back the part that was modified. */
12782 static void depth_buffer2_test(void)
12784 static const struct
12786 struct vec3 position;
12787 DWORD diffuse;
12789 quad[] =
12791 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
12792 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
12793 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
12794 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
12797 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
12798 IDirect3DDevice9 *device;
12799 unsigned int i, j;
12800 D3DVIEWPORT9 vp;
12801 IDirect3D9 *d3d;
12802 D3DCOLOR color;
12803 ULONG refcount;
12804 HWND window;
12805 HRESULT hr;
12807 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12808 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12809 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12810 ok(!!d3d, "Failed to create a D3D object.\n");
12811 if (!(device = create_device(d3d, window, window, TRUE)))
12813 skip("Failed to create a D3D device, skipping tests.\n");
12814 goto done;
12817 vp.X = 0;
12818 vp.Y = 0;
12819 vp.Width = 640;
12820 vp.Height = 480;
12821 vp.MinZ = 0.0;
12822 vp.MaxZ = 1.0;
12824 hr = IDirect3DDevice9_SetViewport(device, &vp);
12825 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12828 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12830 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12832 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12834 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12835 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12836 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12838 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12839 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
12840 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12841 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
12842 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
12843 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12844 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12845 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12847 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
12848 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12849 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12850 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12852 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12853 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12854 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
12855 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12857 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
12858 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
12860 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12862 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12863 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12866 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12868 hr = IDirect3DDevice9_BeginScene(device);
12869 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12871 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12872 hr = IDirect3DDevice9_EndScene(device);
12873 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12875 for (i = 0; i < 4; ++i)
12877 for (j = 0; j < 4; ++j)
12879 unsigned int x = 80 * ((2 * j) + 1);
12880 unsigned int y = 60 * ((2 * i) + 1);
12881 color = getPixelColor(device, x, y);
12882 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
12883 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
12887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12888 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12890 IDirect3DSurface9_Release(backbuffer);
12891 IDirect3DSurface9_Release(rt2);
12892 IDirect3DSurface9_Release(rt1);
12893 refcount = IDirect3DDevice9_Release(device);
12894 ok(!refcount, "Device has %u references left.\n", refcount);
12895 done:
12896 IDirect3D9_Release(d3d);
12897 DestroyWindow(window);
12900 static void depth_blit_test(void)
12902 static const struct
12904 struct vec3 position;
12905 DWORD diffuse;
12907 quad1[] =
12909 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
12910 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
12911 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
12912 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
12914 quad2[] =
12916 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
12917 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
12918 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
12919 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
12921 static const DWORD expected_colors[4][4] =
12923 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12924 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12925 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
12926 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12929 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
12930 IDirect3DDevice9 *device;
12931 RECT src_rect, dst_rect;
12932 unsigned int i, j;
12933 D3DVIEWPORT9 vp;
12934 IDirect3D9 *d3d;
12935 D3DCOLOR color;
12936 ULONG refcount;
12937 HWND window;
12938 HRESULT hr;
12940 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12941 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12942 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12943 ok(!!d3d, "Failed to create a D3D object.\n");
12944 if (!(device = create_device(d3d, window, window, TRUE)))
12946 skip("Failed to create a D3D device, skipping tests.\n");
12947 goto done;
12950 vp.X = 0;
12951 vp.Y = 0;
12952 vp.Width = 640;
12953 vp.Height = 480;
12954 vp.MinZ = 0.0;
12955 vp.MaxZ = 1.0;
12957 hr = IDirect3DDevice9_SetViewport(device, &vp);
12958 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12960 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12961 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12962 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
12963 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12964 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
12965 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
12966 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
12967 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12968 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
12969 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
12971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12972 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12974 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12976 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12977 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12978 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12981 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12982 SetRect(&dst_rect, 0, 0, 480, 360);
12983 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
12984 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12985 SetRect(&dst_rect, 0, 0, 320, 240);
12986 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
12987 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12989 /* Partial blit. */
12990 SetRect(&src_rect, 0, 0, 320, 240);
12991 SetRect(&dst_rect, 0, 0, 320, 240);
12992 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
12993 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12994 /* Flipped. */
12995 SetRect(&src_rect, 0, 0, 640, 480);
12996 SetRect(&dst_rect, 0, 480, 640, 0);
12997 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
12998 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12999 /* Full, explicit. */
13000 SetRect(&src_rect, 0, 0, 640, 480);
13001 SetRect(&dst_rect, 0, 0, 640, 480);
13002 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13003 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13004 /* Filtered blit. */
13005 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
13006 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13007 /* Depth -> color blit.*/
13008 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
13009 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13010 IDirect3DSurface9_Release(backbuffer);
13011 /* Full surface, different sizes */
13012 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
13013 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13014 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
13015 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13017 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
13018 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
13020 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13021 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
13022 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13025 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13026 hr = IDirect3DDevice9_BeginScene(device);
13027 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13028 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13029 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13032 hr = IDirect3DDevice9_EndScene(device);
13033 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13035 for (i = 0; i < 4; ++i)
13037 for (j = 0; j < 4; ++j)
13039 unsigned int x = 80 * ((2 * j) + 1);
13040 unsigned int y = 60 * ((2 * i) + 1);
13041 color = getPixelColor(device, x, y);
13042 ok(color_match(color, expected_colors[i][j], 0),
13043 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13047 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13048 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13050 IDirect3DSurface9_Release(ds3);
13051 IDirect3DSurface9_Release(ds2);
13052 IDirect3DSurface9_Release(ds1);
13053 refcount = IDirect3DDevice9_Release(device);
13054 ok(!refcount, "Device has %u references left.\n", refcount);
13055 done:
13056 IDirect3D9_Release(d3d);
13057 DestroyWindow(window);
13060 static void intz_test(void)
13062 static const DWORD ps_code[] =
13064 0xffff0200, /* ps_2_0 */
13065 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13066 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13067 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13068 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13069 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13070 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13071 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13072 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13073 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13074 0x0000ffff, /* end */
13076 struct
13078 float x, y, z;
13079 float s, t, p, q;
13081 quad[] =
13083 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13084 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13085 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13086 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13088 half_quad_1[] =
13090 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13091 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13092 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13093 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13095 half_quad_2[] =
13097 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13098 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13099 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13100 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13102 struct
13104 UINT x, y;
13105 D3DCOLOR color;
13107 expected_colors[] =
13109 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13110 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13111 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13112 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13113 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13114 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13115 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13116 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13119 IDirect3DSurface9 *original_rt, *rt;
13120 IDirect3DTexture9 *texture;
13121 IDirect3DPixelShader9 *ps;
13122 IDirect3DDevice9 *device;
13123 IDirect3DSurface9 *ds;
13124 IDirect3D9 *d3d;
13125 ULONG refcount;
13126 D3DCAPS9 caps;
13127 HWND window;
13128 HRESULT hr;
13129 UINT i;
13131 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13132 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13133 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13134 ok(!!d3d, "Failed to create a D3D object.\n");
13135 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13136 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
13138 skip("No INTZ support, skipping INTZ test.\n");
13139 goto done;
13141 if (!(device = create_device(d3d, window, window, TRUE)))
13143 skip("Failed to create a D3D device, skipping tests.\n");
13144 goto done;
13147 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13148 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13149 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13151 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13152 IDirect3DDevice9_Release(device);
13153 goto done;
13155 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13157 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13158 IDirect3DDevice9_Release(device);
13159 goto done;
13162 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13163 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13165 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13166 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13167 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13168 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13169 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13170 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13171 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13172 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13174 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13175 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13177 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13179 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13180 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13181 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13183 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13185 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13186 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13187 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13188 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13189 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13190 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13191 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13192 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13194 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13196 /* Render offscreen, using the INTZ texture as depth buffer */
13197 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13198 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13199 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13200 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13201 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13202 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13203 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13204 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13206 /* Setup the depth/stencil surface. */
13207 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13208 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13210 hr = IDirect3DDevice9_BeginScene(device);
13211 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13213 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13214 hr = IDirect3DDevice9_EndScene(device);
13215 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13217 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13218 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13219 IDirect3DSurface9_Release(ds);
13220 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13221 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13222 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13223 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13224 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13225 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13227 /* Read the depth values back. */
13228 hr = IDirect3DDevice9_BeginScene(device);
13229 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13231 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13232 hr = IDirect3DDevice9_EndScene(device);
13233 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13235 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13237 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13238 ok(color_match(color, expected_colors[i].color, 1),
13239 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13240 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13243 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13244 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13246 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13247 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13248 IDirect3DTexture9_Release(texture);
13250 /* Render onscreen while using the INTZ texture as depth buffer */
13251 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13252 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13253 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13254 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13255 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13256 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13257 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13258 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13260 /* Setup the depth/stencil surface. */
13261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13262 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13264 hr = IDirect3DDevice9_BeginScene(device);
13265 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13267 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13268 hr = IDirect3DDevice9_EndScene(device);
13269 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13271 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13272 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13273 IDirect3DSurface9_Release(ds);
13274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13275 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13276 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13277 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13279 /* Read the depth values back. */
13280 hr = IDirect3DDevice9_BeginScene(device);
13281 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13283 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13284 hr = IDirect3DDevice9_EndScene(device);
13285 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13287 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13289 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13290 ok(color_match(color, expected_colors[i].color, 1),
13291 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13292 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13295 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13296 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13298 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13299 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13300 IDirect3DTexture9_Release(texture);
13302 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
13303 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13304 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13305 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13306 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13308 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13309 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13310 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13311 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13312 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13313 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13315 /* Setup the depth/stencil surface. */
13316 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13317 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13319 hr = IDirect3DDevice9_BeginScene(device);
13320 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
13322 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13323 hr = IDirect3DDevice9_EndScene(device);
13324 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13326 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13327 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13329 hr = IDirect3DDevice9_BeginScene(device);
13330 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
13332 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13333 hr = IDirect3DDevice9_EndScene(device);
13334 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13336 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13337 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13338 IDirect3DSurface9_Release(ds);
13339 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13340 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13341 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13342 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13344 /* Read the depth values back. */
13345 hr = IDirect3DDevice9_BeginScene(device);
13346 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13348 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13349 hr = IDirect3DDevice9_EndScene(device);
13350 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13352 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13354 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13355 ok(color_match(color, expected_colors[i].color, 1),
13356 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13357 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13360 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13361 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13363 IDirect3DTexture9_Release(texture);
13364 IDirect3DPixelShader9_Release(ps);
13365 IDirect3DSurface9_Release(original_rt);
13366 IDirect3DSurface9_Release(rt);
13367 refcount = IDirect3DDevice9_Release(device);
13368 ok(!refcount, "Device has %u references left.\n", refcount);
13369 done:
13370 IDirect3D9_Release(d3d);
13371 DestroyWindow(window);
13374 static void shadow_test(void)
13376 static const DWORD ps_code[] =
13378 0xffff0200, /* ps_2_0 */
13379 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13380 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13381 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13382 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13383 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13384 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13385 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13386 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13387 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
13388 0x0000ffff, /* end */
13390 struct
13392 D3DFORMAT format;
13393 const char *name;
13395 formats[] =
13397 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
13398 {D3DFMT_D32, "D3DFMT_D32"},
13399 {D3DFMT_D15S1, "D3DFMT_D15S1"},
13400 {D3DFMT_D24S8, "D3DFMT_D24S8"},
13401 {D3DFMT_D24X8, "D3DFMT_D24X8"},
13402 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
13403 {D3DFMT_D16, "D3DFMT_D16"},
13404 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
13405 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
13407 struct
13409 float x, y, z;
13410 float s, t, p, q;
13412 quad[] =
13414 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
13415 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
13416 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
13417 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
13419 struct
13421 UINT x, y;
13422 D3DCOLOR color;
13424 expected_colors[] =
13426 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13427 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13428 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13429 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13430 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13431 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13432 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13433 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13436 IDirect3DSurface9 *original_ds, *original_rt, *rt;
13437 IDirect3DPixelShader9 *ps;
13438 IDirect3DDevice9 *device;
13439 IDirect3D9 *d3d;
13440 ULONG refcount;
13441 D3DCAPS9 caps;
13442 HWND window;
13443 HRESULT hr;
13444 UINT i;
13446 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13447 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13448 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13449 ok(!!d3d, "Failed to create a D3D object.\n");
13450 if (!(device = create_device(d3d, window, window, TRUE)))
13452 skip("Failed to create a D3D device, skipping tests.\n");
13453 goto done;
13456 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13457 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13458 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13460 skip("No pixel shader 2.0 support, skipping shadow test.\n");
13461 IDirect3DDevice9_Release(device);
13462 goto done;
13465 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13466 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13467 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13468 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13470 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
13471 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13472 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13473 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13474 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13476 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13477 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13478 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13479 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13480 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13481 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13483 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13485 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13487 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13488 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13489 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13490 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13491 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13492 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13493 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13494 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13495 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13496 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13498 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
13500 D3DFORMAT format = formats[i].format;
13501 IDirect3DTexture9 *texture;
13502 IDirect3DSurface9 *ds;
13503 unsigned int j;
13505 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13506 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
13507 continue;
13509 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
13510 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
13511 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13513 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13514 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13516 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13517 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13519 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13520 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13522 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13523 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13525 /* Setup the depth/stencil surface. */
13526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13527 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_BeginScene(device);
13530 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13532 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13533 hr = IDirect3DDevice9_EndScene(device);
13534 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13536 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13537 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13538 IDirect3DSurface9_Release(ds);
13540 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13541 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13543 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13544 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13546 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13547 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13549 /* Do the actual shadow mapping. */
13550 hr = IDirect3DDevice9_BeginScene(device);
13551 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13553 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13554 hr = IDirect3DDevice9_EndScene(device);
13555 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13557 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13558 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13559 IDirect3DTexture9_Release(texture);
13561 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
13563 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
13564 ok(color_match(color, expected_colors[j].color, 0),
13565 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
13566 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
13567 formats[i].name, color);
13570 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13571 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13574 IDirect3DPixelShader9_Release(ps);
13575 IDirect3DSurface9_Release(original_ds);
13576 IDirect3DSurface9_Release(original_rt);
13577 IDirect3DSurface9_Release(rt);
13578 refcount = IDirect3DDevice9_Release(device);
13579 ok(!refcount, "Device has %u references left.\n", refcount);
13580 done:
13581 IDirect3D9_Release(d3d);
13582 DestroyWindow(window);
13585 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
13587 static const struct
13589 struct vec3 position;
13590 DWORD diffuse;
13592 quad1[] =
13594 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
13595 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
13596 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
13597 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
13599 quad2[] =
13601 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
13602 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
13603 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
13604 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
13606 D3DCOLOR color;
13607 HRESULT hr;
13609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
13610 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13612 hr = IDirect3DDevice9_BeginScene(device);
13613 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13615 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13616 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
13619 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13620 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13621 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
13624 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13626 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13628 hr = IDirect3DDevice9_EndScene(device);
13629 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13631 color = getPixelColor(device, 1, 240);
13632 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
13633 color = getPixelColor(device, 638, 240);
13634 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
13636 color = getPixelColor(device, 1, 241);
13637 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
13638 color = getPixelColor(device, 638, 241);
13639 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
13642 static void clip_planes_test(void)
13644 IDirect3DSurface9 *offscreen_surface, *original_rt;
13645 IDirect3DTexture9 *offscreen = NULL;
13646 IDirect3DVertexShader9 *shader;
13647 IDirect3DDevice9 *device;
13648 IDirect3D9 *d3d;
13649 ULONG refcount;
13650 D3DCAPS9 caps;
13651 HWND window;
13652 HRESULT hr;
13654 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
13655 static const DWORD shader_code[] =
13657 0xfffe0200, /* vs_2_0 */
13658 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13659 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
13660 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13661 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
13662 0x0000ffff /* end */
13665 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13666 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13667 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13668 ok(!!d3d, "Failed to create a D3D object.\n");
13669 if (!(device = create_device(d3d, window, window, TRUE)))
13671 skip("Failed to create a D3D device, skipping tests.\n");
13672 goto done;
13675 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13676 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13677 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13679 skip("No vs_2_0 support, skipping tests.\n");
13680 IDirect3DDevice9_Release(device);
13681 goto done;
13684 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13685 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13688 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13690 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13692 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13693 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13694 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13696 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13697 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
13698 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13699 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
13701 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
13703 clip_planes(device, "Onscreen FFP");
13705 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
13706 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13707 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
13708 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13709 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
13710 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13712 clip_planes(device, "Offscreen FFP");
13714 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13715 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13717 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13718 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
13719 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13720 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
13722 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13723 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13725 clip_planes(device, "Onscreen vertex shader");
13727 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
13728 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13730 clip_planes(device, "Offscreen vertex shader");
13732 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13733 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13735 IDirect3DVertexShader9_Release(shader);
13736 IDirect3DSurface9_Release(original_rt);
13737 IDirect3DSurface9_Release(offscreen_surface);
13738 IDirect3DTexture9_Release(offscreen);
13739 refcount = IDirect3DDevice9_Release(device);
13740 ok(!refcount, "Device has %u references left.\n", refcount);
13741 done:
13742 IDirect3D9_Release(d3d);
13743 DestroyWindow(window);
13746 static void fp_special_test(void)
13748 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
13749 static const DWORD vs_header[] =
13751 0xfffe0200, /* vs_2_0 */
13752 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
13753 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
13754 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13755 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
13758 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
13759 static const DWORD vs_pow[] =
13760 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
13761 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
13762 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
13763 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
13764 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
13765 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
13766 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
13767 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
13768 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
13769 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
13770 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
13772 static const DWORD vs_footer[] =
13774 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
13775 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
13776 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
13777 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
13778 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
13779 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
13780 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
13781 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
13782 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
13783 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
13784 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
13785 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
13786 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
13787 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
13788 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13789 0x0000ffff, /* end */
13792 static const struct
13794 const char *name;
13795 const DWORD *ops;
13796 DWORD size;
13797 D3DCOLOR r500;
13798 D3DCOLOR r600;
13799 D3DCOLOR nv40;
13800 D3DCOLOR nv50;
13801 D3DCOLOR warp;
13803 vs_body[] =
13805 /* The basic ideas here are:
13806 * 2.0 * +/-INF == +/-INF
13807 * NAN != NAN
13809 * The vertex shader value is written to the red component, with 0.0
13810 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
13811 * result in 0x00. The pixel shader value is written to the green
13812 * component, but here 0.0 also results in 0x00. The actual value is
13813 * written to the blue component.
13815 * There are considerable differences between graphics cards in how
13816 * these are handled, but pow and nrm never generate INF or NAN on
13817 * real hardware. */
13818 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13819 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
13820 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
13821 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13822 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13823 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13824 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13825 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13826 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
13827 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13828 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13831 static const DWORD ps_code[] =
13833 0xffff0200, /* ps_2_0 */
13834 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
13835 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
13836 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
13837 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
13838 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
13839 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
13840 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
13841 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
13842 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
13843 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
13844 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
13845 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
13846 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
13847 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
13848 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
13849 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
13850 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
13851 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
13852 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
13853 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
13854 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
13855 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
13856 0x0000ffff, /* end */
13859 struct
13861 float x, y, z;
13862 float s;
13864 quad[] =
13866 { -1.0f, 1.0f, 0.0f, 0.0f},
13867 { 1.0f, 1.0f, 1.0f, 0.0f},
13868 { -1.0f, -1.0f, 0.0f, 0.0f},
13869 { 1.0f, -1.0f, 1.0f, 0.0f},
13872 IDirect3DPixelShader9 *ps;
13873 IDirect3DDevice9 *device;
13874 UINT body_size = 0;
13875 IDirect3D9 *d3d;
13876 DWORD *vs_code;
13877 ULONG refcount;
13878 D3DCAPS9 caps;
13879 HWND window;
13880 HRESULT hr;
13881 UINT i;
13883 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13884 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13885 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13886 ok(!!d3d, "Failed to create a D3D object.\n");
13887 if (!(device = create_device(d3d, window, window, TRUE)))
13889 skip("Failed to create a D3D device, skipping tests.\n");
13890 goto done;
13893 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13894 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13895 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13897 skip("No shader model 2.0 support, skipping floating point specials test.\n");
13898 IDirect3DDevice9_Release(device);
13899 goto done;
13902 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
13903 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13905 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13906 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13907 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13908 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13911 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
13914 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13916 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
13918 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
13921 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
13922 memcpy(vs_code, vs_header, sizeof(vs_header));
13924 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
13926 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
13927 IDirect3DVertexShader9 *vs;
13928 D3DCOLOR color;
13930 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
13931 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
13932 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
13934 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13935 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
13936 hr = IDirect3DDevice9_SetVertexShader(device, vs);
13937 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
13939 hr = IDirect3DDevice9_BeginScene(device);
13940 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13942 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13943 hr = IDirect3DDevice9_EndScene(device);
13944 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13946 color = getPixelColor(device, 320, 240);
13947 ok(color_match(color, vs_body[i].r500, 1)
13948 || color_match(color, vs_body[i].r600, 1)
13949 || color_match(color, vs_body[i].nv40, 1)
13950 || color_match(color, vs_body[i].nv50, 1)
13951 || broken(color_match(color, vs_body[i].warp, 1)),
13952 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
13953 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
13955 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13956 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13958 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13959 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
13960 IDirect3DVertexShader9_Release(vs);
13963 HeapFree(GetProcessHeap(), 0, vs_code);
13965 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13966 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13967 IDirect3DPixelShader9_Release(ps);
13968 refcount = IDirect3DDevice9_Release(device);
13969 ok(!refcount, "Device has %u references left.\n", refcount);
13970 done:
13971 IDirect3D9_Release(d3d);
13972 DestroyWindow(window);
13975 static void srgbwrite_format_test(void)
13977 IDirect3D9 *d3d;
13978 IDirect3DSurface9 *rt, *backbuffer;
13979 IDirect3DTexture9 *texture;
13980 IDirect3DDevice9 *device;
13981 ULONG refcount;
13982 HWND window;
13983 HRESULT hr;
13984 int i;
13985 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
13986 static const struct
13988 D3DFORMAT fmt;
13989 const char *name;
13991 formats[] =
13993 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
13994 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
13995 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
13996 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
13997 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
13999 static const struct
14001 float x, y, z;
14002 float u, v;
14004 quad[] =
14006 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14007 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14008 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14009 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14012 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14013 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14014 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14015 ok(!!d3d, "Failed to create a D3D object.\n");
14016 if (!(device = create_device(d3d, window, window, TRUE)))
14018 skip("Failed to create a D3D device, skipping tests.\n");
14019 goto done;
14022 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
14023 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14024 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
14025 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
14026 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14027 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14028 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
14029 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14031 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
14033 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14034 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
14036 skip("Format %s not supported as render target, skipping test.\n",
14037 formats[i].name);
14038 continue;
14041 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
14042 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
14043 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14044 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14045 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14047 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
14048 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14049 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14050 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
14052 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14054 hr = IDirect3DDevice9_BeginScene(device);
14055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
14058 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
14059 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
14060 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
14061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
14065 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
14066 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14067 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14068 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
14069 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
14070 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14071 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
14072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14073 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14074 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14075 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
14077 hr = IDirect3DDevice9_EndScene(device);
14078 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14080 IDirect3DSurface9_Release(rt);
14081 IDirect3DTexture9_Release(texture);
14083 color = getPixelColor(device, 360, 240);
14084 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14085 D3DUSAGE_QUERY_SRGBWRITE,
14086 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
14088 /* Big slop for R5G6B5 */
14089 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
14090 formats[i].name, color_srgb, color);
14092 else
14094 /* Big slop for R5G6B5 */
14095 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
14096 formats[i].name, color_rgb, color);
14099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14100 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14103 IDirect3DSurface9_Release(backbuffer);
14104 refcount = IDirect3DDevice9_Release(device);
14105 ok(!refcount, "Device has %u references left.\n", refcount);
14106 done:
14107 IDirect3D9_Release(d3d);
14108 DestroyWindow(window);
14111 static void ds_size_test(void)
14113 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
14114 IDirect3DDevice9 *device;
14115 DWORD num_passes;
14116 IDirect3D9 *d3d;
14117 ULONG refcount;
14118 HWND window;
14119 HRESULT hr;
14121 static const struct
14123 float x, y, z;
14125 quad[] =
14127 {-1.0f, -1.0f, 0.0f},
14128 {-1.0f, 1.0f, 0.0f},
14129 { 1.0f, -1.0f, 0.0f},
14130 { 1.0f, 1.0f, 0.0f},
14133 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14134 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14135 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14136 ok(!!d3d, "Failed to create a D3D object.\n");
14137 if (!(device = create_device(d3d, window, window, TRUE)))
14139 skip("Failed to create a D3D device, skipping tests.\n");
14140 goto done;
14143 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14144 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14145 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
14146 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
14147 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
14148 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
14150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14151 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
14153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14154 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14155 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
14156 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14158 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14159 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14160 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14161 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14162 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14163 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
14164 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
14165 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14166 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14167 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14168 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14169 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14170 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14172 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
14173 * but does not change the surface's contents. */
14174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
14175 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
14176 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
14177 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
14178 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
14179 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
14181 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
14183 /* Turning on any depth-related state results in a ValidateDevice failure */
14184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14185 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14186 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14187 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14188 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14190 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14192 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14193 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14194 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14195 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14197 /* Try to draw with the device in an invalid state. */
14198 hr = IDirect3DDevice9_BeginScene(device);
14199 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14200 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14201 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14202 hr = IDirect3DDevice9_EndScene(device);
14203 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14205 /* Don't check the resulting draw unless we find an app that needs it. On
14206 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
14207 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
14208 * 0.0 for all pixels, even those that are covered by the depth buffer. */
14210 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
14211 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14212 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
14213 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14214 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14215 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14217 IDirect3DSurface9_Release(readback);
14218 IDirect3DSurface9_Release(ds);
14219 IDirect3DSurface9_Release(rt);
14220 IDirect3DSurface9_Release(old_rt);
14221 IDirect3DSurface9_Release(old_ds);
14222 refcount = IDirect3DDevice9_Release(device);
14223 ok(!refcount, "Device has %u references left.\n", refcount);
14224 done:
14225 IDirect3D9_Release(d3d);
14226 DestroyWindow(window);
14229 static void unbound_sampler_test(void)
14231 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
14232 IDirect3DSurface9 *rt, *old_rt;
14233 IDirect3DDevice9 *device;
14234 IDirect3D9 *d3d;
14235 ULONG refcount;
14236 D3DCAPS9 caps;
14237 DWORD color;
14238 HWND window;
14239 HRESULT hr;
14241 static const DWORD ps_code[] =
14243 0xffff0200, /* ps_2_0 */
14244 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14245 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14246 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14247 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14248 0x0000ffff, /* end */
14250 static const DWORD ps_code_cube[] =
14252 0xffff0200, /* ps_2_0 */
14253 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
14254 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14255 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14256 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14257 0x0000ffff, /* end */
14259 static const DWORD ps_code_volume[] =
14261 0xffff0200, /* ps_2_0 */
14262 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
14263 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14264 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14265 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14266 0x0000ffff, /* end */
14269 static const struct
14271 float x, y, z;
14272 float u, v;
14274 quad[] =
14276 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14277 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14278 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14279 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14282 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14283 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14284 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14285 ok(!!d3d, "Failed to create a D3D object.\n");
14286 if (!(device = create_device(d3d, window, window, TRUE)))
14288 skip("Failed to create a D3D device, skipping tests.\n");
14289 goto done;
14292 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14293 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14294 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14296 skip("No ps_2_0 support, skipping tests.\n");
14297 IDirect3DDevice9_Release(device);
14298 goto done;
14300 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
14302 skip("No cube / volume texture support, skipping tests.\n");
14303 IDirect3DDevice9_Release(device);
14304 goto done;
14307 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14308 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
14310 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14311 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14312 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
14313 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14314 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
14315 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14317 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
14318 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14320 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14321 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14323 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14324 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14326 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
14327 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
14329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
14330 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
14332 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14333 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14335 hr = IDirect3DDevice9_BeginScene(device);
14336 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14337 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14338 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14339 hr = IDirect3DDevice9_EndScene(device);
14340 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14342 color = getPixelColorFromSurface(rt, 32, 32);
14343 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14345 /* Now try with a cube texture */
14346 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
14347 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14349 hr = IDirect3DDevice9_BeginScene(device);
14350 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14352 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14353 hr = IDirect3DDevice9_EndScene(device);
14354 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14356 color = getPixelColorFromSurface(rt, 32, 32);
14357 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14359 /* And then with a volume texture */
14360 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
14361 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14363 hr = IDirect3DDevice9_BeginScene(device);
14364 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
14365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14366 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
14367 hr = IDirect3DDevice9_EndScene(device);
14368 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
14370 color = getPixelColorFromSurface(rt, 32, 32);
14371 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14373 IDirect3DSurface9_Release(rt);
14374 IDirect3DSurface9_Release(old_rt);
14375 IDirect3DPixelShader9_Release(ps);
14376 IDirect3DPixelShader9_Release(ps_cube);
14377 IDirect3DPixelShader9_Release(ps_volume);
14378 refcount = IDirect3DDevice9_Release(device);
14379 ok(!refcount, "Device has %u references left.\n", refcount);
14380 done:
14381 IDirect3D9_Release(d3d);
14382 DestroyWindow(window);
14385 static void update_surface_test(void)
14387 static const BYTE blocks[][8] =
14389 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
14390 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
14391 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
14392 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
14393 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
14394 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
14395 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
14397 static const struct
14399 UINT x, y;
14400 D3DCOLOR color;
14402 expected_colors[] =
14404 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
14405 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
14406 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
14407 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
14408 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14409 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14410 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
14412 static const struct
14414 float x, y, z, w;
14415 float u, v;
14417 tri[] =
14419 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
14420 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
14421 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
14423 static const RECT rect_2x2 = {0, 0, 2, 2};
14424 static const struct
14426 UINT src_level;
14427 UINT dst_level;
14428 const RECT *r;
14429 HRESULT hr;
14431 block_size_tests[] =
14433 {1, 0, NULL, D3D_OK},
14434 {0, 1, NULL, D3DERR_INVALIDCALL},
14435 {5, 4, NULL, D3DERR_INVALIDCALL},
14436 {4, 5, NULL, D3DERR_INVALIDCALL},
14437 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
14438 {5, 5, &rect_2x2, D3D_OK},
14441 IDirect3DSurface9 *src_surface, *dst_surface;
14442 IDirect3DTexture9 *src_tex, *dst_tex;
14443 IDirect3DDevice9 *device;
14444 IDirect3D9 *d3d;
14445 ULONG refcount;
14446 UINT count, i;
14447 HWND window;
14448 HRESULT hr;
14450 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14451 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14452 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14453 ok(!!d3d, "Failed to create a D3D object.\n");
14454 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14455 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
14457 skip("DXT1 not supported, skipping tests.\n");
14458 goto done;
14460 if (!(device = create_device(d3d, window, window, TRUE)))
14462 skip("Failed to create a D3D device, skipping tests.\n");
14463 goto done;
14466 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
14467 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
14468 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
14469 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
14471 count = IDirect3DTexture9_GetLevelCount(src_tex);
14472 ok(count == 7, "Got level count %u, expected 7.\n", count);
14474 for (i = 0; i < count; ++i)
14476 UINT row_count, block_count, x, y;
14477 D3DSURFACE_DESC desc;
14478 BYTE *row, *block;
14479 D3DLOCKED_RECT r;
14481 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
14482 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
14484 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
14485 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
14487 row_count = ((desc.Height + 3) & ~3) / 4;
14488 block_count = ((desc.Width + 3) & ~3) / 4;
14489 row = r.pBits;
14491 for (y = 0; y < row_count; ++y)
14493 block = row;
14494 for (x = 0; x < block_count; ++x)
14496 memcpy(block, blocks[i], sizeof(blocks[i]));
14497 block += sizeof(blocks[i]);
14499 row += r.Pitch;
14502 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
14503 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
14506 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
14508 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
14509 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14510 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
14511 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14513 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
14514 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
14515 hr, i, block_size_tests[i].hr);
14517 IDirect3DSurface9_Release(dst_surface);
14518 IDirect3DSurface9_Release(src_surface);
14521 for (i = 0; i < count; ++i)
14523 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
14524 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14525 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
14526 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14528 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
14529 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
14531 IDirect3DSurface9_Release(dst_surface);
14532 IDirect3DSurface9_Release(src_surface);
14535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14536 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14537 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14538 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14539 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
14540 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14541 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
14542 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14543 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14544 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14545 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14546 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
14549 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14551 hr = IDirect3DDevice9_BeginScene(device);
14552 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14553 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
14554 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14555 hr = IDirect3DDevice9_EndScene(device);
14556 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14558 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14560 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14561 ok(color_match(color, expected_colors[i].color, 0),
14562 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14563 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14566 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14567 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14569 IDirect3DTexture9_Release(dst_tex);
14570 IDirect3DTexture9_Release(src_tex);
14571 refcount = IDirect3DDevice9_Release(device);
14572 ok(!refcount, "Device has %u references left.\n", refcount);
14573 done:
14574 IDirect3D9_Release(d3d);
14575 DestroyWindow(window);
14578 static void multisample_get_rtdata_test(void)
14580 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
14581 IDirect3DDevice9 *device;
14582 IDirect3D9 *d3d;
14583 ULONG refcount;
14584 HWND window;
14585 HRESULT hr;
14587 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14588 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14589 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14590 ok(!!d3d, "Failed to create a D3D object.\n");
14591 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14592 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14594 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
14595 goto done;
14597 if (!(device = create_device(d3d, window, window, TRUE)))
14599 skip("Failed to create a D3D device, skipping tests.\n");
14600 goto done;
14603 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
14604 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14605 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14606 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
14607 D3DPOOL_SYSTEMMEM, &readback, NULL);
14608 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14610 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14611 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14612 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14613 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14615 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14616 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14617 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14618 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
14621 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14622 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
14623 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
14625 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
14626 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14627 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14628 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
14630 IDirect3DSurface9_Release(original_ds);
14631 IDirect3DSurface9_Release(original_rt);
14632 IDirect3DSurface9_Release(readback);
14633 IDirect3DSurface9_Release(rt);
14634 refcount = IDirect3DDevice9_Release(device);
14635 ok(!refcount, "Device has %u references left.\n", refcount);
14636 done:
14637 IDirect3D9_Release(d3d);
14638 DestroyWindow(window);
14641 static void multisampled_depth_buffer_test(void)
14643 IDirect3DDevice9 *device = 0;
14644 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
14645 IDirect3D9 *d3d;
14646 D3DCAPS9 caps;
14647 HRESULT hr;
14648 D3DPRESENT_PARAMETERS present_parameters;
14649 unsigned int i;
14650 static const struct
14652 float x, y, z;
14653 D3DCOLOR color;
14655 quad_1[] =
14657 { -1.0f, 1.0f, 0.0f, 0xffff0000},
14658 { 1.0f, 1.0f, 1.0f, 0xffff0000},
14659 { -1.0f, -1.0f, 0.0f, 0xffff0000},
14660 { 1.0f, -1.0f, 1.0f, 0xffff0000},
14662 quad_2[] =
14664 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
14665 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
14666 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
14667 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
14669 static const struct
14671 UINT x, y;
14672 D3DCOLOR color;
14674 expected_colors[] =
14676 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14677 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14678 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14679 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14680 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14681 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14682 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14683 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14686 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14687 ok(!!d3d, "Failed to create a D3D object.\n");
14689 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14690 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14692 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
14693 IDirect3D9_Release(d3d);
14694 return;
14696 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14697 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14699 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
14700 IDirect3D9_Release(d3d);
14701 return;
14704 ZeroMemory(&present_parameters, sizeof(present_parameters));
14705 present_parameters.Windowed = TRUE;
14706 present_parameters.hDeviceWindow = create_window();
14707 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14708 present_parameters.BackBufferWidth = 640;
14709 present_parameters.BackBufferHeight = 480;
14710 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14711 present_parameters.EnableAutoDepthStencil = TRUE;
14712 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14713 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
14715 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14716 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
14717 &present_parameters, &device);
14718 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14720 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14721 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14722 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14724 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
14725 goto cleanup;
14728 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14729 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14730 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14731 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14732 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14733 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14735 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14736 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14737 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
14738 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14741 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14743 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14745 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14747 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14748 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14749 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14751 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14752 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14754 /* Render onscreen and then offscreen */
14755 hr = IDirect3DDevice9_BeginScene(device);
14756 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14757 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14758 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14759 hr = IDirect3DDevice9_EndScene(device);
14760 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14762 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
14763 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14764 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14765 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14767 hr = IDirect3DDevice9_BeginScene(device);
14768 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14770 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14771 hr = IDirect3DDevice9_EndScene(device);
14772 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14774 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
14775 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14777 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14779 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14780 ok(color_match(color, expected_colors[i].color, 1),
14781 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14782 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14785 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14786 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14787 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14788 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14790 /* Render offscreen and then onscreen */
14791 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14792 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14793 IDirect3DSurface9_Release(ds);
14794 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14795 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
14796 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14797 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14799 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14800 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14802 hr = IDirect3DDevice9_BeginScene(device);
14803 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14805 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14806 hr = IDirect3DDevice9_EndScene(device);
14807 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14809 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14810 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14811 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14812 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14814 hr = IDirect3DDevice9_BeginScene(device);
14815 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14817 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14818 hr = IDirect3DDevice9_EndScene(device);
14819 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14821 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
14822 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14824 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14826 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14827 ok(color_match(color, expected_colors[i].color, 1),
14828 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14829 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14832 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14833 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14835 IDirect3DSurface9_Release(ds);
14836 IDirect3DSurface9_Release(readback);
14837 IDirect3DSurface9_Release(rt);
14838 IDirect3DSurface9_Release(original_rt);
14839 cleanup_device(device);
14841 ZeroMemory(&present_parameters, sizeof(present_parameters));
14842 present_parameters.Windowed = TRUE;
14843 present_parameters.hDeviceWindow = create_window();
14844 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14845 present_parameters.BackBufferWidth = 640;
14846 present_parameters.BackBufferHeight = 480;
14847 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14848 present_parameters.EnableAutoDepthStencil = TRUE;
14849 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14850 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
14852 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14853 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
14854 &present_parameters, &device);
14855 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
14858 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
14860 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14861 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14862 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14863 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14864 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14865 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14866 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14867 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
14868 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14870 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14871 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14872 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14873 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14874 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14875 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14876 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14877 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14880 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14882 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14884 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14886 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14887 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14888 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14890 /* Render to a multisampled offscreen frame buffer and then blit to
14891 * the onscreen (not multisampled) frame buffer. */
14892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14893 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14895 hr = IDirect3DDevice9_BeginScene(device);
14896 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14898 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14899 hr = IDirect3DDevice9_EndScene(device);
14900 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14902 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14903 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14904 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
14905 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14907 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14908 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14909 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
14910 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14912 hr = IDirect3DDevice9_BeginScene(device);
14913 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14915 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14916 hr = IDirect3DDevice9_EndScene(device);
14917 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14919 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
14920 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14922 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14924 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14925 ok(color_match(color, expected_colors[i].color, 1),
14926 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14927 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14930 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14931 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14933 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14934 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14935 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14936 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
14938 IDirect3DSurface9_Release(original_ds);
14939 IDirect3DSurface9_Release(original_rt);
14940 IDirect3DSurface9_Release(ds);
14941 IDirect3DSurface9_Release(readback);
14942 IDirect3DSurface9_Release(rt);
14943 cleanup:
14944 cleanup_device(device);
14945 IDirect3D9_Release(d3d);
14948 static void resz_test(void)
14950 IDirect3DDevice9 *device = 0;
14951 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
14952 D3DCAPS9 caps;
14953 HRESULT hr;
14954 D3DPRESENT_PARAMETERS present_parameters;
14955 unsigned int i;
14956 static const DWORD ps_code[] =
14958 0xffff0200, /* ps_2_0 */
14959 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14960 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14961 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14962 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14963 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14964 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
14965 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
14966 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
14967 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
14968 0x0000ffff, /* end */
14970 struct
14972 float x, y, z;
14973 float s, t, p, q;
14975 quad[] =
14977 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14978 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14979 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14980 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14982 struct
14984 UINT x, y;
14985 D3DCOLOR color;
14987 expected_colors[] =
14989 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
14990 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
14991 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
14992 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
14993 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
14994 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
14995 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
14996 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
14998 IDirect3DTexture9 *texture;
14999 IDirect3DPixelShader9 *ps;
15000 IDirect3D9 *d3d;
15001 DWORD value;
15003 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15004 ok(!!d3d, "Failed to create a D3D object.\n");
15006 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15007 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15009 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
15010 IDirect3D9_Release(d3d);
15011 return;
15013 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15014 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15016 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
15017 IDirect3D9_Release(d3d);
15018 return;
15021 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15022 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
15024 skip("No INTZ support, skipping RESZ test.\n");
15025 IDirect3D9_Release(d3d);
15026 return;
15029 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15030 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
15032 skip("No RESZ support, skipping RESZ test.\n");
15033 IDirect3D9_Release(d3d);
15034 return;
15037 ZeroMemory(&present_parameters, sizeof(present_parameters));
15038 present_parameters.Windowed = TRUE;
15039 present_parameters.hDeviceWindow = create_window();
15040 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15041 present_parameters.BackBufferWidth = 640;
15042 present_parameters.BackBufferHeight = 480;
15043 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15044 present_parameters.EnableAutoDepthStencil = FALSE;
15045 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15046 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15048 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15049 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15050 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15052 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15053 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15054 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15056 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
15057 cleanup_device(device);
15058 IDirect3D9_Release(d3d);
15059 return;
15061 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15063 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
15064 cleanup_device(device);
15065 IDirect3D9_Release(d3d);
15066 return;
15069 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15070 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15072 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15073 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15074 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15075 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15076 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15077 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15078 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15079 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15081 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15082 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15083 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15084 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15085 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15086 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15087 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15088 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15089 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15090 IDirect3DSurface9_Release(intz_ds);
15091 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15092 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15094 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15095 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15097 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15099 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15101 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15103 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15105 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15106 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15107 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15108 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15109 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15110 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15111 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15112 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15113 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15114 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15116 /* Render offscreen (multisampled), blit the depth buffer
15117 * into the INTZ texture and then check its contents */
15118 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15119 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15120 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15121 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15122 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15123 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15125 hr = IDirect3DDevice9_BeginScene(device);
15126 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15128 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15130 /* The destination depth texture has to be bound to sampler 0 */
15131 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15132 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15134 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
15135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15136 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15138 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15140 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15141 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15142 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15144 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15146 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15148 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15150 /* The actual multisampled depth buffer resolve happens here */
15151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15152 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15153 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15154 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15156 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15157 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15158 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15159 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15161 /* Read the depth values back */
15162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15163 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15164 hr = IDirect3DDevice9_EndScene(device);
15165 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15167 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15169 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15170 ok(color_match(color, expected_colors[i].color, 1),
15171 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15172 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15175 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15176 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15178 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15179 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15180 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15181 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15182 IDirect3DSurface9_Release(ds);
15183 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15184 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15185 IDirect3DTexture9_Release(texture);
15186 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15187 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15188 IDirect3DPixelShader9_Release(ps);
15189 IDirect3DSurface9_Release(readback);
15190 IDirect3DSurface9_Release(original_rt);
15191 IDirect3DSurface9_Release(rt);
15192 cleanup_device(device);
15195 ZeroMemory(&present_parameters, sizeof(present_parameters));
15196 present_parameters.Windowed = TRUE;
15197 present_parameters.hDeviceWindow = create_window();
15198 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15199 present_parameters.BackBufferWidth = 640;
15200 present_parameters.BackBufferHeight = 480;
15201 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15202 present_parameters.EnableAutoDepthStencil = TRUE;
15203 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15204 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15206 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15207 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15208 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15210 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15211 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15212 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15213 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15214 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15215 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15216 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15217 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15218 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15219 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15220 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15221 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15222 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15223 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15224 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15225 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15226 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15227 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15228 IDirect3DSurface9_Release(intz_ds);
15229 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15230 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15232 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15233 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15241 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15243 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15244 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15246 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15247 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15248 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15249 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15250 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15251 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15252 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15254 /* Render onscreen, blit the depth buffer into the INTZ texture
15255 * and then check its contents */
15256 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15257 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15258 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15259 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15260 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15261 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15263 hr = IDirect3DDevice9_BeginScene(device);
15264 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15266 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15267 hr = IDirect3DDevice9_EndScene(device);
15268 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15270 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15271 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15274 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15276 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15278 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15279 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15280 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15282 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15284 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15286 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15288 /* The actual multisampled depth buffer resolve happens here */
15289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15290 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15291 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15292 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15294 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15295 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15296 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15297 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15299 /* Read the depth values back */
15300 hr = IDirect3DDevice9_BeginScene(device);
15301 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15303 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15304 hr = IDirect3DDevice9_EndScene(device);
15305 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15307 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15309 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15310 ok(color_match(color, expected_colors[i].color, 1),
15311 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15312 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15315 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15316 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15319 /* Test edge cases - try with no texture at all */
15320 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15321 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15322 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15323 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15325 hr = IDirect3DDevice9_BeginScene(device);
15326 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15328 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15329 hr = IDirect3DDevice9_EndScene(device);
15330 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15333 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15335 /* With a non-multisampled depth buffer */
15336 IDirect3DSurface9_Release(ds);
15337 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15338 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15340 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15341 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15342 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15343 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15344 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15345 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15347 hr = IDirect3DDevice9_BeginScene(device);
15348 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15349 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15350 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15352 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15353 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15355 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15356 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15358 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15360 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15362 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15364 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15366 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15368 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15369 hr = IDirect3DDevice9_EndScene(device);
15370 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15373 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15375 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15376 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15378 /* Read the depth values back. */
15379 hr = IDirect3DDevice9_BeginScene(device);
15380 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15382 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15383 hr = IDirect3DDevice9_EndScene(device);
15384 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15386 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15388 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15389 ok(color_match(color, expected_colors[i].color, 1),
15390 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15391 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15394 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15395 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15397 /* Without a current depth-stencil buffer set */
15398 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15399 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15400 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15401 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15403 hr = IDirect3DDevice9_BeginScene(device);
15404 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15405 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15406 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15407 hr = IDirect3DDevice9_EndScene(device);
15408 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15411 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15413 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15414 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15415 IDirect3DSurface9_Release(ds);
15416 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15417 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15418 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15419 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15420 IDirect3DTexture9_Release(texture);
15421 IDirect3DPixelShader9_Release(ps);
15422 IDirect3DSurface9_Release(readback);
15423 IDirect3DSurface9_Release(original_rt);
15424 cleanup_device(device);
15425 IDirect3D9_Release(d3d);
15428 static void zenable_test(void)
15430 static const struct
15432 struct vec4 position;
15433 D3DCOLOR diffuse;
15435 tquad[] =
15437 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
15438 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
15439 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
15440 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
15442 IDirect3DDevice9 *device;
15443 IDirect3D9 *d3d;
15444 D3DCOLOR color;
15445 ULONG refcount;
15446 D3DCAPS9 caps;
15447 HWND window;
15448 HRESULT hr;
15449 UINT x, y;
15450 UINT i, j;
15451 UINT test;
15452 IDirect3DSurface9 *ds;
15454 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15455 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15456 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15457 ok(!!d3d, "Failed to create a D3D object.\n");
15458 if (!(device = create_device(d3d, window, window, TRUE)))
15460 skip("Failed to create a D3D device, skipping tests.\n");
15461 goto done;
15464 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15465 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
15467 for (test = 0; test < 2; ++test)
15469 /* The Windows 8 testbot (WARP) appears to clip with
15470 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
15471 static const D3DCOLOR expected_broken[] =
15473 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
15474 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
15475 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
15476 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
15479 if (!test)
15481 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15482 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
15484 else
15486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15487 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
15488 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15489 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
15490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
15491 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
15494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15496 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
15497 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15498 hr = IDirect3DDevice9_BeginScene(device);
15499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
15501 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15502 hr = IDirect3DDevice9_EndScene(device);
15503 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15505 for (i = 0; i < 4; ++i)
15507 for (j = 0; j < 4; ++j)
15509 x = 80 * ((2 * j) + 1);
15510 y = 60 * ((2 * i) + 1);
15511 color = getPixelColor(device, x, y);
15512 ok(color_match(color, 0x0000ff00, 1)
15513 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
15514 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
15515 x, y, color, test);
15519 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15520 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15523 IDirect3DSurface9_Release(ds);
15525 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15526 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15528 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
15529 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
15531 static const DWORD vs_code[] =
15533 0xfffe0101, /* vs_1_1 */
15534 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15535 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15536 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
15537 0x0000ffff
15539 static const DWORD ps_code[] =
15541 0xffff0101, /* ps_1_1 */
15542 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
15543 0x0000ffff /* end */
15545 static const struct vec3 quad[] =
15547 {-1.0f, -1.0f, -0.5f},
15548 {-1.0f, 1.0f, -0.5f},
15549 { 1.0f, -1.0f, 1.5f},
15550 { 1.0f, 1.0f, 1.5f},
15552 static const D3DCOLOR expected[] =
15554 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
15555 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
15556 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
15557 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
15559 /* The Windows 8 testbot (WARP) appears to not clip z for regular
15560 * vertices either. */
15561 static const D3DCOLOR expected_broken[] =
15563 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
15564 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
15565 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
15566 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
15569 IDirect3DVertexShader9 *vs;
15570 IDirect3DPixelShader9 *ps;
15572 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15573 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15574 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15575 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
15576 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15577 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15578 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15579 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15580 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15581 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15583 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
15584 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15585 hr = IDirect3DDevice9_BeginScene(device);
15586 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15588 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15589 hr = IDirect3DDevice9_EndScene(device);
15590 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15592 for (i = 0; i < 4; ++i)
15594 for (j = 0; j < 4; ++j)
15596 x = 80 * ((2 * j) + 1);
15597 y = 60 * ((2 * i) + 1);
15598 color = getPixelColor(device, x, y);
15599 ok(color_match(color, expected[i * 4 + j], 1)
15600 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
15601 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
15605 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15606 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15608 IDirect3DPixelShader9_Release(ps);
15609 IDirect3DVertexShader9_Release(vs);
15612 refcount = IDirect3DDevice9_Release(device);
15613 ok(!refcount, "Device has %u references left.\n", refcount);
15614 done:
15615 IDirect3D9_Release(d3d);
15616 DestroyWindow(window);
15619 static void fog_special_test(void)
15621 static const struct
15623 struct vec3 position;
15624 D3DCOLOR diffuse;
15626 quad[] =
15628 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
15629 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
15630 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
15631 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
15633 static const struct
15635 DWORD vertexmode, tablemode;
15636 BOOL vs, ps;
15637 D3DCOLOR color_left, color_right;
15639 tests[] =
15641 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
15642 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
15643 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
15644 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
15646 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
15647 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
15648 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
15649 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
15651 static const DWORD pixel_shader_code[] =
15653 0xffff0101, /* ps_1_1 */
15654 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
15655 0x0000ffff
15657 static const DWORD vertex_shader_code[] =
15659 0xfffe0101, /* vs_1_1 */
15660 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15661 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
15662 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15663 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
15664 0x0000ffff
15666 static const D3DMATRIX identity =
15668 1.0f, 0.0f, 0.0f, 0.0f,
15669 0.0f, 1.0f, 0.0f, 0.0f,
15670 0.0f, 0.0f, 1.0f, 0.0f,
15671 0.0f, 0.0f, 0.0f, 1.0f,
15672 }}};
15673 union
15675 float f;
15676 DWORD d;
15677 } conv;
15678 DWORD color;
15679 HRESULT hr;
15680 unsigned int i;
15681 IDirect3DPixelShader9 *ps;
15682 IDirect3DVertexShader9 *vs;
15683 IDirect3DDevice9 *device;
15684 IDirect3D9 *d3d;
15685 ULONG refcount;
15686 D3DCAPS9 caps;
15687 HWND window;
15689 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15690 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15691 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15692 ok(!!d3d, "Failed to create a D3D object.\n");
15693 if (!(device = create_device(d3d, window, window, TRUE)))
15695 skip("Failed to create a D3D device, skipping tests.\n");
15696 goto done;
15699 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15700 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15701 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
15703 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
15704 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
15706 else
15708 skip("Vertex Shaders not supported, skipping some fog tests.\n");
15709 vs = NULL;
15711 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
15713 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
15714 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15716 else
15718 skip("Pixel Shaders not supported, skipping some fog tests.\n");
15719 ps = NULL;
15722 /* The table fog tests seem to depend on the projection matrix explicitly
15723 * being set to an identity matrix, even though that's the default.
15724 * (AMD Radeon HD 6310, Windows 7) */
15725 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
15726 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
15728 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15729 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15731 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
15732 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
15733 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
15734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
15735 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
15737 conv.f = 0.5f;
15738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
15739 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
15740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
15741 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
15743 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
15745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15746 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15748 if (!tests[i].vs)
15750 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15751 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15753 else if (vs)
15755 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15756 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15758 else
15760 continue;
15763 if (!tests[i].ps)
15765 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15766 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15768 else if (ps)
15770 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15771 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15773 else
15775 continue;
15778 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
15779 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
15780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
15781 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
15783 hr = IDirect3DDevice9_BeginScene(device);
15784 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15786 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15787 hr = IDirect3DDevice9_EndScene(device);
15788 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15790 color = getPixelColor(device, 310, 240);
15791 ok(color_match(color, tests[i].color_left, 1),
15792 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
15793 color = getPixelColor(device, 330, 240);
15794 ok(color_match(color, tests[i].color_right, 1),
15795 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
15797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15798 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15801 if (vs)
15802 IDirect3DVertexShader9_Release(vs);
15803 if (ps)
15804 IDirect3DPixelShader9_Release(ps);
15805 refcount = IDirect3DDevice9_Release(device);
15806 ok(!refcount, "Device has %u references left.\n", refcount);
15807 done:
15808 IDirect3D9_Release(d3d);
15809 DestroyWindow(window);
15812 static void volume_srgb_test(void)
15814 HRESULT hr;
15815 unsigned int i, j;
15816 IDirect3DVolumeTexture9 *tex1, *tex2;
15817 D3DPOOL pool;
15818 D3DLOCKED_BOX locked_box;
15819 IDirect3DDevice9 *device;
15820 IDirect3D9 *d3d;
15821 D3DCOLOR color;
15822 ULONG refcount;
15823 HWND window;
15825 static const struct
15827 BOOL srgb;
15828 DWORD color;
15830 tests[] =
15832 /* Try toggling on and off */
15833 { FALSE, 0x007f7f7f },
15834 { TRUE, 0x00363636 },
15835 { FALSE, 0x007f7f7f },
15837 static const struct
15839 struct vec3 pos;
15840 struct vec3 texcrd;
15842 quad[] =
15844 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15845 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15846 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15847 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15850 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15851 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15852 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15853 ok(!!d3d, "Failed to create a D3D object.\n");
15854 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15855 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
15857 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
15858 goto done;
15860 if (!(device = create_device(d3d, window, window, TRUE)))
15862 skip("Failed to create a D3D device, skipping tests.\n");
15863 goto done;
15866 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15867 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
15868 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15869 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
15870 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
15871 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
15872 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
15873 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
15875 for (i = 0; i < 2; i++)
15877 if (!i)
15878 pool = D3DPOOL_SYSTEMMEM;
15879 else
15880 pool = D3DPOOL_MANAGED;
15882 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
15883 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15884 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
15885 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15886 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
15887 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
15888 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15890 if (!i)
15892 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
15893 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
15894 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15895 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
15896 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
15897 IDirect3DVolumeTexture9_Release(tex1);
15899 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
15900 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15901 IDirect3DVolumeTexture9_Release(tex2);
15903 else
15905 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
15906 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15907 IDirect3DVolumeTexture9_Release(tex1);
15910 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
15912 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
15913 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
15915 hr = IDirect3DDevice9_BeginScene(device);
15916 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15918 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15919 hr = IDirect3DDevice9_EndScene(device);
15920 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15922 color = getPixelColor(device, 320, 240);
15923 ok(color_match(color, tests[j].color, 2),
15924 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
15926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15927 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15931 refcount = IDirect3DDevice9_Release(device);
15932 ok(!refcount, "Device has %u references left.\n", refcount);
15933 done:
15934 IDirect3D9_Release(d3d);
15935 DestroyWindow(window);
15938 static void volume_dxt5_test(void)
15940 IDirect3DVolumeTexture9 *texture;
15941 IDirect3DDevice9 *device;
15942 D3DLOCKED_BOX box;
15943 IDirect3D9 *d3d;
15944 unsigned int i;
15945 ULONG refcount;
15946 DWORD color;
15947 HWND window;
15948 HRESULT hr;
15950 static const char texture_data[] =
15952 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
15953 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
15954 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
15955 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
15956 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
15958 static const struct
15960 struct vec3 position;
15961 struct vec3 texcrd;
15963 quads[] =
15965 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
15966 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
15967 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
15968 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
15970 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
15971 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
15972 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
15973 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
15975 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
15977 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15978 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15979 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15980 ok(!!d3d, "Failed to create a D3D object.\n");
15981 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15982 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
15984 skip("DXT5 volume textures are not supported, skipping test.\n");
15985 goto done;
15987 if (!(device = create_device(d3d, window, window, TRUE)))
15989 skip("Failed to create a D3D device, skipping tests.\n");
15990 goto done;
15993 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
15994 D3DPOOL_MANAGED, &texture, NULL);
15995 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15997 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
15998 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15999 memcpy(box.pBits, texture_data, sizeof(texture_data));
16000 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16001 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16004 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16005 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16006 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16007 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16008 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16009 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16010 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16011 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16012 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16013 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16014 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
16016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16017 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16018 hr = IDirect3DDevice9_BeginScene(device);
16019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16020 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16021 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16022 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16023 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16024 hr = IDirect3DDevice9_EndScene(device);
16025 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16027 for (i = 0; i < 4; i++)
16029 color = getPixelColor(device, 80 + 160 * i, 240);
16030 ok (color_match(color, expected_colors[i], 1),
16031 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
16034 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16035 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16036 IDirect3DVolumeTexture9_Release(texture);
16037 refcount = IDirect3DDevice9_Release(device);
16038 ok(!refcount, "Device has %u references left.\n", refcount);
16039 done:
16040 IDirect3D9_Release(d3d);
16041 DestroyWindow(window);
16044 static void volume_v16u16_test(void)
16046 IDirect3DVolumeTexture9 *texture;
16047 IDirect3DPixelShader9 *shader;
16048 IDirect3DDevice9 *device;
16049 D3DLOCKED_BOX box;
16050 IDirect3D9 *d3d;
16051 unsigned int i;
16052 ULONG refcount;
16053 D3DCAPS9 caps;
16054 SHORT *texel;
16055 DWORD color;
16056 HWND window;
16057 HRESULT hr;
16059 static const struct
16061 struct vec3 position;
16062 struct vec3 texcrd;
16064 quads[] =
16066 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16067 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16068 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16069 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16071 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16072 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16073 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16074 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16076 static const DWORD shader_code[] =
16078 0xffff0101, /* ps_1_1 */
16079 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
16080 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
16081 0x00000042, 0xb00f0000, /* tex t0 */
16082 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
16083 0x0000ffff /* end */
16086 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16087 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16088 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16089 ok(!!d3d, "Failed to create a D3D object.\n");
16090 if (!(device = create_device(d3d, window, window, TRUE)))
16092 skip("Failed to create a D3D device, skipping tests.\n");
16093 goto done;
16096 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16097 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16098 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
16100 skip("No ps_1_1 support, skipping tests.\n");
16101 IDirect3DDevice9_Release(device);
16102 goto done;
16104 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16105 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
16107 skip("Volume V16U16 textures are not supported, skipping test.\n");
16108 IDirect3DDevice9_Release(device);
16109 goto done;
16112 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16113 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16114 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
16115 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16116 hr = IDirect3DDevice9_SetPixelShader(device, shader);
16117 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16118 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16119 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
16121 for (i = 0; i < 2; i++)
16123 D3DPOOL pool;
16125 if (i)
16126 pool = D3DPOOL_SYSTEMMEM;
16127 else
16128 pool = D3DPOOL_MANAGED;
16130 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16131 pool, &texture, NULL);
16132 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16134 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16135 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16137 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
16138 texel[0] = 32767;
16139 texel[1] = 32767;
16140 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
16141 texel[0] = -32768;
16142 texel[1] = 0;
16143 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
16144 texel[0] = -16384;
16145 texel[1] = 16384;
16146 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
16147 texel[0] = 0;
16148 texel[1] = 0;
16150 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16151 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16153 if (i)
16155 IDirect3DVolumeTexture9 *texture2;
16157 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16158 D3DPOOL_DEFAULT, &texture2, NULL);
16159 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16161 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
16162 (IDirect3DBaseTexture9 *)texture2);
16163 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16165 IDirect3DVolumeTexture9_Release(texture);
16166 texture = texture2;
16169 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
16170 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16172 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16173 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16174 hr = IDirect3DDevice9_BeginScene(device);
16175 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16177 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16180 hr = IDirect3DDevice9_EndScene(device);
16181 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16183 color = getPixelColor(device, 120, 160);
16184 ok (color_match(color, 0x000080ff, 2),
16185 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
16186 color = getPixelColor(device, 120, 400);
16187 ok (color_match(color, 0x00ffffff, 2),
16188 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
16189 color = getPixelColor(device, 360, 160);
16190 ok (color_match(color, 0x007f7fff, 2),
16191 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
16192 color = getPixelColor(device, 360, 400);
16193 ok (color_match(color, 0x0040c0ff, 2),
16194 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
16196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16197 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16199 IDirect3DVolumeTexture9_Release(texture);
16202 IDirect3DPixelShader9_Release(shader);
16203 refcount = IDirect3DDevice9_Release(device);
16204 ok(!refcount, "Device has %u references left.\n", refcount);
16205 done:
16206 IDirect3D9_Release(d3d);
16207 DestroyWindow(window);
16210 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
16212 HRESULT hr;
16213 static const struct
16215 struct vec3 position;
16216 struct vec2 texcoord;
16218 quad[] =
16220 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
16221 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
16222 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
16223 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
16226 hr = IDirect3DDevice9_BeginScene(device);
16227 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
16229 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16230 hr = IDirect3DDevice9_EndScene(device);
16231 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16234 static void add_dirty_rect_test(void)
16236 HRESULT hr;
16237 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
16238 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
16239 IDirect3DDevice9 *device;
16240 IDirect3D9 *d3d;
16241 unsigned int i;
16242 ULONG refcount;
16243 DWORD *texel;
16244 HWND window;
16245 D3DLOCKED_RECT locked_rect;
16246 static const RECT part_rect = {96, 96, 160, 160};
16247 DWORD color;
16249 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16250 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16251 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16252 ok(!!d3d, "Failed to create a D3D object.\n");
16253 if (!(device = create_device(d3d, window, window, TRUE)))
16255 skip("Failed to create a D3D device, skipping tests.\n");
16256 IDirect3D9_Release(d3d);
16257 DestroyWindow(window);
16258 return;
16261 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16262 D3DPOOL_DEFAULT, &tex_dst1, NULL);
16263 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16264 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16265 D3DPOOL_DEFAULT, &tex_dst2, NULL);
16266 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16267 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16268 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
16269 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16270 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16271 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
16272 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16273 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16274 D3DPOOL_MANAGED, &tex_managed, NULL);
16275 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16277 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
16278 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16279 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
16280 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16281 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
16282 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16283 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
16284 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16286 fill_surface(surface_src_red, 0x00ff0000, 0);
16287 fill_surface(surface_src_green, 0x0000ff00, 0);
16289 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
16290 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16291 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16292 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16293 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16294 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16296 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16297 (IDirect3DBaseTexture9 *)tex_dst1);
16298 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16300 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
16301 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
16302 (IDirect3DBaseTexture9 *)tex_dst2);
16303 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16304 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16305 (IDirect3DBaseTexture9 *)tex_dst2);
16306 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16308 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
16309 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16310 add_dirty_rect_test_draw(device);
16311 color = getPixelColor(device, 320, 240);
16312 ok(color_match(color, 0x0000ff00, 1),
16313 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16315 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16317 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
16318 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16319 add_dirty_rect_test_draw(device);
16320 color = getPixelColor(device, 320, 240);
16321 todo_wine ok(color_match(color, 0x00ff0000, 1),
16322 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16323 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16324 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16326 /* AddDirtyRect on the destination is ignored. */
16327 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
16328 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16329 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16330 (IDirect3DBaseTexture9 *)tex_dst2);
16331 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16332 add_dirty_rect_test_draw(device);
16333 color = getPixelColor(device, 320, 240);
16334 todo_wine ok(color_match(color, 0x00ff0000, 1),
16335 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16336 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16337 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16339 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
16340 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16341 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16342 (IDirect3DBaseTexture9 *)tex_dst2);
16343 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16344 add_dirty_rect_test_draw(device);
16345 color = getPixelColor(device, 320, 240);
16346 todo_wine ok(color_match(color, 0x00ff0000, 1),
16347 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16348 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16349 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16351 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
16352 * tracking is supported. */
16353 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
16354 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16355 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16356 (IDirect3DBaseTexture9 *)tex_dst2);
16357 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16358 add_dirty_rect_test_draw(device);
16359 color = getPixelColor(device, 320, 240);
16360 ok(color_match(color, 0x0000ff00, 1),
16361 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16362 color = getPixelColor(device, 1, 1);
16363 todo_wine ok(color_match(color, 0x00ff0000, 1),
16364 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16366 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16368 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
16369 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16370 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16371 (IDirect3DBaseTexture9 *)tex_dst2);
16372 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16373 add_dirty_rect_test_draw(device);
16374 color = getPixelColor(device, 1, 1);
16375 ok(color_match(color, 0x0000ff00, 1),
16376 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16378 /* Locks with NO_DIRTY_UPDATE are ignored. */
16379 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
16380 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16381 (IDirect3DBaseTexture9 *)tex_dst2);
16382 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16383 add_dirty_rect_test_draw(device);
16384 color = getPixelColor(device, 320, 240);
16385 todo_wine ok(color_match(color, 0x0000ff00, 1),
16386 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16387 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16388 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16390 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
16391 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
16392 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16393 (IDirect3DBaseTexture9 *)tex_dst2);
16394 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16395 add_dirty_rect_test_draw(device);
16396 color = getPixelColor(device, 320, 240);
16397 todo_wine ok(color_match(color, 0x0000ff00, 1),
16398 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16399 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16400 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16402 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
16403 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16404 (IDirect3DBaseTexture9 *)tex_dst2);
16405 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16406 add_dirty_rect_test_draw(device);
16407 color = getPixelColor(device, 320, 240);
16408 ok(color_match(color, 0x000000ff, 1),
16409 "Expected color 0x000000ff, got 0x%08x.\n", color);
16410 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16411 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16413 /* Maps without either of these flags record a dirty rectangle. */
16414 fill_surface(surface_src_green, 0x00ffffff, 0);
16415 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16416 (IDirect3DBaseTexture9 *)tex_dst2);
16417 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16418 add_dirty_rect_test_draw(device);
16419 color = getPixelColor(device, 320, 240);
16420 ok(color_match(color, 0x00ffffff, 1),
16421 "Expected color 0x00ffffff, got 0x%08x.\n", color);
16422 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16423 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16425 /* Partial LockRect works just like a partial AddDirtyRect call. */
16426 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
16427 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16428 texel = locked_rect.pBits;
16429 for (i = 0; i < 64; i++)
16430 texel[i] = 0x00ff00ff;
16431 for (i = 1; i < 64; i++)
16432 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
16433 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
16434 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16435 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16436 (IDirect3DBaseTexture9 *)tex_dst2);
16437 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16438 add_dirty_rect_test_draw(device);
16439 color = getPixelColor(device, 320, 240);
16440 ok(color_match(color, 0x00ff00ff, 1),
16441 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
16442 color = getPixelColor(device, 1, 1);
16443 ok(color_match(color, 0x00ffffff, 1),
16444 "Expected color 0x00ffffff, got 0x%08x.\n", color);
16445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16446 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16448 fill_surface(surface_src_red, 0x00ff0000, 0);
16449 fill_surface(surface_src_green, 0x0000ff00, 0);
16451 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16452 (IDirect3DBaseTexture9 *)tex_dst1);
16453 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16454 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
16455 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16456 add_dirty_rect_test_draw(device);
16457 color = getPixelColor(device, 320, 240);
16458 ok(color_match(color, 0x0000ff00, 1),
16459 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16460 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16461 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16463 /* UpdateSurface ignores the missing dirty marker. */
16464 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
16465 (IDirect3DBaseTexture9 *)tex_dst2);
16466 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
16467 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
16468 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
16469 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16470 add_dirty_rect_test_draw(device);
16471 color = getPixelColor(device, 320, 240);
16472 ok(color_match(color, 0x0000ff00, 1),
16473 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16474 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16475 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16477 fill_surface(surface_managed, 0x00ff0000, 0);
16478 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
16479 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16480 add_dirty_rect_test_draw(device);
16481 color = getPixelColor(device, 320, 240);
16482 ok(color_match(color, 0x00ff0000, 1),
16483 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16484 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16485 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16487 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
16488 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
16489 add_dirty_rect_test_draw(device);
16490 color = getPixelColor(device, 320, 240);
16491 ok(color_match(color, 0x00ff0000, 1),
16492 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16493 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16494 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16496 /* AddDirtyRect uploads the new contents.
16497 * Side note, not tested in the test: Partial surface updates work, and two separate
16498 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
16499 * untested. */
16500 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16501 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16502 add_dirty_rect_test_draw(device);
16503 color = getPixelColor(device, 320, 240);
16504 ok(color_match(color, 0x0000ff00, 1),
16505 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16506 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16507 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16509 /* So does EvictManagedResources. */
16510 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
16511 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16512 hr = IDirect3DDevice9_EvictManagedResources(device);
16513 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
16514 add_dirty_rect_test_draw(device);
16515 color = getPixelColor(device, 320, 240);
16516 ok(color_match(color, 0x000000ff, 1),
16517 "Expected color 0x000000ff, got 0x%08x.\n", color);
16518 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16519 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16521 /* AddDirtyRect on a locked texture is allowed. */
16522 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
16523 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16524 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
16525 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16526 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
16527 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16529 /* Redundant AddDirtyRect calls are ok. */
16530 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16531 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16532 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16533 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16535 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
16536 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16537 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16538 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16539 IDirect3DSurface9_Release(surface_dst2);
16540 IDirect3DSurface9_Release(surface_managed);
16541 IDirect3DSurface9_Release(surface_src_red);
16542 IDirect3DSurface9_Release(surface_src_green);
16543 IDirect3DTexture9_Release(tex_src_red);
16544 IDirect3DTexture9_Release(tex_src_green);
16545 IDirect3DTexture9_Release(tex_dst1);
16546 IDirect3DTexture9_Release(tex_dst2);
16547 IDirect3DTexture9_Release(tex_managed);
16548 refcount = IDirect3DDevice9_Release(device);
16549 ok(!refcount, "Device has %u references left.\n", refcount);
16550 IDirect3D9_Release(d3d);
16551 DestroyWindow(window);
16554 static void test_per_stage_constant(void)
16556 IDirect3DDevice9 *device;
16557 IDirect3D9 *d3d;
16558 D3DCOLOR color;
16559 ULONG refcount;
16560 D3DCAPS9 caps;
16561 HWND window;
16562 HRESULT hr;
16564 static const struct
16566 struct vec3 position;
16567 D3DCOLOR diffuse;
16569 quad[] =
16571 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
16572 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
16573 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
16574 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
16577 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16578 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16579 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16580 ok(!!d3d, "Failed to create a D3D object.\n");
16581 if (!(device = create_device(d3d, window, window, TRUE)))
16583 skip("Failed to create a D3D device, skipping tests.\n");
16584 goto done;
16587 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16588 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16589 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
16591 skip("Per-stage constants not supported, skipping tests.\n");
16592 IDirect3DDevice9_Release(device);
16593 goto done;
16596 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16597 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16598 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
16599 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
16601 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
16603 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16605 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16607 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
16608 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16609 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
16610 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16611 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16612 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16614 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
16615 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16617 hr = IDirect3DDevice9_BeginScene(device);
16618 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16619 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16620 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16621 hr = IDirect3DDevice9_EndScene(device);
16622 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16624 color = getPixelColor(device, 320, 240);
16625 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
16626 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16627 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16629 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
16630 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16632 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
16633 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16635 hr = IDirect3DDevice9_BeginScene(device);
16636 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16638 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16639 hr = IDirect3DDevice9_EndScene(device);
16640 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16642 color = getPixelColor(device, 320, 240);
16643 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
16644 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16645 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16647 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
16648 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
16651 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16653 hr = IDirect3DDevice9_BeginScene(device);
16654 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16656 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16657 hr = IDirect3DDevice9_EndScene(device);
16658 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16660 color = getPixelColor(device, 320, 240);
16661 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
16662 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16663 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16665 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
16666 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16667 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
16668 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16669 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
16670 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16672 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
16673 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16675 hr = IDirect3DDevice9_BeginScene(device);
16676 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16678 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16679 hr = IDirect3DDevice9_EndScene(device);
16680 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16682 color = getPixelColor(device, 320, 240);
16683 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
16684 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16685 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16687 refcount = IDirect3DDevice9_Release(device);
16688 ok(!refcount, "Device has %u references left.\n", refcount);
16689 done:
16690 IDirect3D9_Release(d3d);
16691 DestroyWindow(window);
16694 static void test_3dc_formats(void)
16696 static const char ati1n_data[] =
16698 /* A 4x4 texture with the color component at 50%. */
16699 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16701 static const char ati2n_data[] =
16703 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
16704 * 0% second component. Second block is the opposite. */
16705 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
16708 static const struct
16710 struct vec3 position;
16711 struct vec2 texcoord;
16713 quads[] =
16715 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
16716 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
16717 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
16718 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
16720 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
16721 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
16722 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
16723 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
16725 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
16726 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
16727 static const struct
16729 struct vec2 position;
16730 D3DCOLOR amd_r500;
16731 D3DCOLOR amd_r600;
16732 D3DCOLOR nvidia_old;
16733 D3DCOLOR nvidia_new;
16735 expected_colors[] =
16737 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
16738 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
16739 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
16740 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
16742 IDirect3D9 *d3d;
16743 IDirect3DDevice9 *device;
16744 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
16745 D3DCAPS9 caps;
16746 D3DLOCKED_RECT rect;
16747 D3DCOLOR color;
16748 ULONG refcount;
16749 HWND window;
16750 HRESULT hr;
16751 unsigned int i;
16753 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16754 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16755 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16756 ok(!!d3d, "Failed to create a D3D object.\n");
16757 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16758 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
16760 skip("ATI1N textures are not supported, skipping test.\n");
16761 goto done;
16763 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16764 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
16766 skip("ATI2N textures are not supported, skipping test.\n");
16767 goto done;
16769 if (!(device = create_device(d3d, window, window, TRUE)))
16771 skip("Failed to create a D3D device, skipping tests.\n");
16772 goto done;
16774 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16775 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16776 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
16778 skip("D3DTA_TEMP not supported, skipping tests.\n");
16779 IDirect3DDevice9_Release(device);
16780 goto done;
16783 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
16784 D3DPOOL_MANAGED, &ati1n_texture, NULL);
16785 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16787 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
16788 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16789 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
16790 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
16791 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16793 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
16794 D3DPOOL_MANAGED, &ati2n_texture, NULL);
16795 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16797 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
16798 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16799 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
16800 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
16801 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16803 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
16804 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16805 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
16806 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16808 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16809 /* The temporary register is initialized to 0. */
16810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
16811 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
16813 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
16814 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
16815 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
16816 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16817 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16818 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16819 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
16821 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16822 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16823 hr = IDirect3DDevice9_BeginScene(device);
16824 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16825 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
16826 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16828 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16829 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
16830 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16832 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16833 hr = IDirect3DDevice9_EndScene(device);
16834 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16836 for (i = 0; i < 4; ++i)
16838 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
16839 ok (color_match(color, expected_colors[i].amd_r500, 1)
16840 || color_match(color, expected_colors[i].amd_r600, 1)
16841 || color_match(color, expected_colors[i].nvidia_old, 1)
16842 || color_match(color, expected_colors[i].nvidia_new, 1),
16843 "Got unexpected color 0x%08x, case %u.\n", color, i);
16846 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16847 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16848 IDirect3DTexture9_Release(ati2n_texture);
16849 IDirect3DTexture9_Release(ati1n_texture);
16850 refcount = IDirect3DDevice9_Release(device);
16851 ok(!refcount, "Device has %u references left.\n", refcount);
16853 done:
16854 IDirect3D9_Release(d3d);
16855 DestroyWindow(window);
16858 static void test_fog_interpolation(void)
16860 HRESULT hr;
16861 IDirect3DDevice9 *device;
16862 IDirect3D9 *d3d;
16863 ULONG refcount;
16864 HWND window;
16865 D3DCOLOR color;
16866 static const struct
16868 struct vec3 position;
16869 D3DCOLOR diffuse;
16870 D3DCOLOR specular;
16872 quad[] =
16874 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
16875 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
16876 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
16877 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
16879 union
16881 DWORD d;
16882 float f;
16883 } conv;
16884 unsigned int i;
16885 static const struct
16887 D3DFOGMODE vfog, tfog;
16888 D3DSHADEMODE shade;
16889 D3DCOLOR middle_color;
16890 BOOL todo;
16892 tests[] =
16894 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
16895 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
16896 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
16897 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
16898 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
16899 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
16900 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
16901 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
16903 static const D3DMATRIX ident_mat =
16905 1.0f, 0.0f, 0.0f, 0.0f,
16906 0.0f, 1.0f, 0.0f, 0.0f,
16907 0.0f, 0.0f, 1.0f, 0.0f,
16908 0.0f, 0.0f, 0.0f, 1.0f
16909 }}};
16910 D3DCAPS9 caps;
16912 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16913 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16914 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16915 ok(!!d3d, "Failed to create a D3D object.\n");
16917 if (!(device = create_device(d3d, window, window, TRUE)))
16919 skip("Failed to create a D3D device, skipping tests.\n");
16920 IDirect3D9_Release(d3d);
16921 DestroyWindow(window);
16922 return;
16925 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16926 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16927 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
16928 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
16930 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
16931 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16933 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16935 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16937 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
16939 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16940 conv.f = 5.0;
16941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
16942 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16944 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16945 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16946 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
16947 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
16948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
16949 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16951 /* Some of the tests seem to depend on the projection matrix explicitly
16952 * being set to an identity matrix, even though that's the default.
16953 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
16954 * the drivers seem to use a static z = 1.0 input for the fog equation.
16955 * The input value is independent of the actual z and w component of
16956 * the vertex position. */
16957 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
16958 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16960 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16962 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
16963 continue;
16965 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
16966 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
16969 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
16971 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
16973 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
16974 hr = IDirect3DDevice9_BeginScene(device);
16975 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16977 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16978 hr = IDirect3DDevice9_EndScene(device);
16979 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16981 color = getPixelColor(device, 0, 240);
16982 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
16983 color = getPixelColor(device, 320, 240);
16984 if (tests[i].todo)
16985 todo_wine ok(color_match(color, tests[i].middle_color, 2),
16986 "Got unexpected color 0x%08x, case %u.\n", color, i);
16987 else
16988 ok(color_match(color, tests[i].middle_color, 2),
16989 "Got unexpected color 0x%08x, case %u.\n", color, i);
16990 color = getPixelColor(device, 639, 240);
16991 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
16992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16993 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16996 refcount = IDirect3DDevice9_Release(device);
16997 ok(!refcount, "Device has %u references left.\n", refcount);
16998 IDirect3D9_Release(d3d);
16999 DestroyWindow(window);
17002 static void test_negative_fixedfunction_fog(void)
17004 HRESULT hr;
17005 IDirect3DDevice9 *device;
17006 IDirect3D9 *d3d;
17007 ULONG refcount;
17008 HWND window;
17009 D3DCOLOR color;
17010 static const struct
17012 struct vec3 position;
17013 D3DCOLOR diffuse;
17015 quad[] =
17017 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
17018 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
17019 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
17020 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
17022 static const struct
17024 struct vec4 position;
17025 D3DCOLOR diffuse;
17027 tquad[] =
17029 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
17030 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
17031 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
17032 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
17034 unsigned int i;
17035 static const D3DMATRIX zero =
17037 1.0f, 0.0f, 0.0f, 0.0f,
17038 0.0f, 1.0f, 0.0f, 0.0f,
17039 0.0f, 0.0f, 0.0f, 0.0f,
17040 0.0f, 0.0f, 0.0f, 1.0f
17041 }}};
17042 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
17043 * have an effect on RHW draws. */
17044 static const D3DMATRIX identity =
17046 1.0f, 0.0f, 0.0f, 0.0f,
17047 0.0f, 1.0f, 0.0f, 0.0f,
17048 0.0f, 0.0f, 1.0f, 0.0f,
17049 0.0f, 0.0f, 0.0f, 1.0f
17050 }}};
17051 static const struct
17053 DWORD pos_type;
17054 const void *quad;
17055 size_t stride;
17056 const D3DMATRIX *matrix;
17057 union
17059 float f;
17060 DWORD d;
17061 } start, end;
17062 D3DFOGMODE vfog, tfog;
17063 DWORD color, color_broken, color_broken2;
17065 tests[] =
17067 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
17069 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
17070 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
17071 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
17072 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
17073 * parameters to 0.0 and 1.0 in the table fog case. */
17074 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
17075 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
17076 /* test_fog_interpolation shows that vertex fog evaluates the fog
17077 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
17078 * that the abs happens before the fog equation is evaluated.
17080 * Vertex fog abs() behavior is the same on all GPUs. */
17081 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
17082 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
17083 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
17084 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
17085 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
17086 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
17088 D3DCAPS9 caps;
17090 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17091 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17092 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17093 ok(!!d3d, "Failed to create a D3D object.\n");
17095 if (!(device = create_device(d3d, window, window, TRUE)))
17097 skip("Failed to create a D3D device, skipping tests.\n");
17098 IDirect3D9_Release(d3d);
17099 DestroyWindow(window);
17100 return;
17103 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17104 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17105 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17106 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
17108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17109 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17111 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17113 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17115 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
17117 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
17119 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17121 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
17122 continue;
17124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
17125 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17127 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
17128 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17129 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
17130 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
17132 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
17134 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
17136 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
17138 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17140 hr = IDirect3DDevice9_BeginScene(device);
17141 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
17143 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17144 hr = IDirect3DDevice9_EndScene(device);
17145 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17147 color = getPixelColor(device, 320, 240);
17148 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
17149 || broken(color_match(color, tests[i].color_broken2, 2)),
17150 "Got unexpected color 0x%08x, case %u.\n", color, i);
17151 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17152 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17155 refcount = IDirect3DDevice9_Release(device);
17156 ok(!refcount, "Device has %u references left.\n", refcount);
17157 IDirect3D9_Release(d3d);
17158 DestroyWindow(window);
17161 static void test_position_index(void)
17163 static const D3DVERTEXELEMENT9 decl_elements[] =
17165 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
17166 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
17167 D3DDECL_END()
17169 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
17170 * but works on Nvidia.
17171 * MSDN is not consistent on this point. */
17172 static const DWORD vs_code[] =
17174 0xfffe0300, /* vs_3_0 */
17175 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17176 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
17177 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
17178 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
17179 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
17180 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
17181 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
17182 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
17183 0x0000ffff /* end */
17185 static const DWORD vs_code_2[] =
17187 0xfffe0300, /* vs_3_0 */
17188 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17189 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
17190 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
17191 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
17192 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
17193 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
17194 0x0000ffff /* end */
17196 static const DWORD ps_code[] =
17198 0xffff0300, /* ps_3_0 */
17199 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
17200 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
17201 0x0000ffff /* end */
17203 static const DWORD ps_code_2[] =
17205 0xffff0300, /* ps_3_0 */
17206 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
17207 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
17208 0x0000ffff /* end */
17210 /* This one is considered invalid by the native shader assembler. */
17211 static const DWORD ps_code_bad[] =
17213 0xffff0300, /* ps_3_0 */
17214 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
17215 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
17216 0x0000ffff /* end */
17218 static const struct
17220 struct vec3 position;
17221 struct vec3 position1;
17223 quad[] =
17225 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
17226 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
17227 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
17228 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
17230 static const struct
17232 struct vec2 position;
17233 D3DCOLOR expected_color;
17234 D3DCOLOR broken_color;
17236 expected_colors[] =
17238 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
17239 {{240, 240}, 0x009f6000, 0x00ff00ff},
17240 {{400, 240}, 0x00609f00, 0x00ff00ff},
17241 {{560, 240}, 0x0020df00, 0x00ff00ff},
17243 IDirect3D9 *d3d;
17244 IDirect3DDevice9 *device;
17245 IDirect3DVertexDeclaration9 *vertex_declaration;
17246 IDirect3DVertexShader9 *vs, *vs2;
17247 IDirect3DPixelShader9 *ps, *ps2;
17248 D3DCAPS9 caps;
17249 D3DCOLOR color;
17250 ULONG refcount;
17251 HWND window;
17252 HRESULT hr;
17253 unsigned int i;
17255 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17256 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17257 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17258 ok(!!d3d, "Failed to create a D3D object.\n");
17259 if (!(device = create_device(d3d, window, window, TRUE)))
17261 skip("Failed to create a D3D device, skipping tests.\n");
17262 goto done;
17265 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17266 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17267 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
17268 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
17270 skip("Shader model 3.0 unsupported, skipping tests.\n");
17271 IDirect3DDevice9_Release(device);
17272 goto done;
17275 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
17276 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
17278 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
17279 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
17281 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
17282 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
17283 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
17284 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
17286 hr = IDirect3DDevice9_SetVertexShader(device, vs);
17287 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
17289 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
17290 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
17292 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
17293 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
17294 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
17295 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
17297 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17298 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17300 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17301 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17302 hr = IDirect3DDevice9_BeginScene(device);
17303 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17305 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17306 hr = IDirect3DDevice9_EndScene(device);
17307 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17309 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
17311 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17312 ok (color_match(color, expected_colors[i].expected_color, 1)
17313 || broken(color_match(color, expected_colors[i].broken_color, 1)),
17314 "Got unexpected color 0x%08x, case %u.\n", color, i);
17317 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
17318 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17320 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17321 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17322 hr = IDirect3DDevice9_BeginScene(device);
17323 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17325 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17326 hr = IDirect3DDevice9_EndScene(device);
17327 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17329 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
17331 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17332 ok (color_match(color, expected_colors[i].expected_color, 1)
17333 || broken(color_match(color, expected_colors[i].broken_color, 1)),
17334 "Got unexpected color 0x%08x, case %u.\n", color, i);
17337 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
17338 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
17340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17341 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17342 hr = IDirect3DDevice9_BeginScene(device);
17343 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17345 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17346 hr = IDirect3DDevice9_EndScene(device);
17347 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17349 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
17351 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17352 ok (color_match(color, expected_colors[i].expected_color, 1),
17353 "Got unexpected color 0x%08x, case %u.\n", color, i);
17356 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17357 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17359 IDirect3DPixelShader9_Release(ps2);
17360 IDirect3DPixelShader9_Release(ps);
17361 IDirect3DVertexShader9_Release(vs2);
17362 IDirect3DVertexShader9_Release(vs);
17363 IDirect3DVertexDeclaration9_Release(vertex_declaration);
17364 refcount = IDirect3DDevice9_Release(device);
17365 ok(!refcount, "Device has %u references left.\n", refcount);
17367 done:
17368 IDirect3D9_Release(d3d);
17369 DestroyWindow(window);
17372 static void test_table_fog_zw(void)
17374 HRESULT hr;
17375 IDirect3DDevice9 *device;
17376 IDirect3D9 *d3d;
17377 ULONG refcount;
17378 HWND window;
17379 D3DCOLOR color;
17380 D3DCAPS9 caps;
17381 static struct
17383 struct vec4 position;
17384 D3DCOLOR diffuse;
17386 quad[] =
17388 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
17389 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
17390 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
17391 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
17393 static const D3DMATRIX identity =
17395 1.0f, 0.0f, 0.0f, 0.0f,
17396 0.0f, 1.0f, 0.0f, 0.0f,
17397 0.0f, 0.0f, 1.0f, 0.0f,
17398 0.0f, 0.0f, 0.0f, 1.0f
17399 }}};
17400 static const struct
17402 float z, w;
17403 D3DZBUFFERTYPE z_test;
17404 D3DCOLOR color;
17406 tests[] =
17408 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
17409 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
17410 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
17411 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
17412 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
17413 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
17414 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
17415 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
17417 unsigned int i;
17419 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17420 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17421 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17422 ok(!!d3d, "Failed to create a D3D object.\n");
17424 if (!(device = create_device(d3d, window, window, TRUE)))
17426 skip("Failed to create a D3D device, skipping tests.\n");
17427 IDirect3D9_Release(d3d);
17428 DestroyWindow(window);
17429 return;
17432 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17433 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17434 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17436 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
17437 goto done;
17440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17441 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17443 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17445 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
17447 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
17448 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
17449 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
17450 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
17452 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17453 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
17454 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17456 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
17458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17459 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17461 quad[0].position.z = tests[i].z;
17462 quad[1].position.z = tests[i].z;
17463 quad[2].position.z = tests[i].z;
17464 quad[3].position.z = tests[i].z;
17465 quad[0].position.w = tests[i].w;
17466 quad[1].position.w = tests[i].w;
17467 quad[2].position.w = tests[i].w;
17468 quad[3].position.w = tests[i].w;
17469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
17470 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17472 hr = IDirect3DDevice9_BeginScene(device);
17473 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
17475 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17476 hr = IDirect3DDevice9_EndScene(device);
17477 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17479 color = getPixelColor(device, 320, 240);
17480 ok(color_match(color, tests[i].color, 2),
17481 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
17482 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17483 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17486 done:
17487 refcount = IDirect3DDevice9_Release(device);
17488 ok(!refcount, "Device has %u references left.\n", refcount);
17489 IDirect3D9_Release(d3d);
17490 DestroyWindow(window);
17493 START_TEST(visual)
17495 D3DADAPTER_IDENTIFIER9 identifier;
17496 IDirect3D9 *d3d;
17497 HRESULT hr;
17499 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
17501 skip("could not create D3D9 object\n");
17502 return;
17505 memset(&identifier, 0, sizeof(identifier));
17506 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
17507 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
17508 trace("Driver string: \"%s\"\n", identifier.Driver);
17509 trace("Description string: \"%s\"\n", identifier.Description);
17510 /* Only Windows XP's default VGA driver should have an empty description */
17511 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
17512 trace("Device name string: \"%s\"\n", identifier.DeviceName);
17513 ok(identifier.DeviceName[0], "Empty device name.\n");
17514 trace("Driver version %d.%d.%d.%d\n",
17515 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
17516 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
17518 IDirect3D9_Release(d3d);
17520 test_sanity();
17521 depth_clamp_test();
17522 stretchrect_test();
17523 lighting_test();
17524 clear_test();
17525 color_fill_test();
17526 fog_test();
17527 test_cube_wrap();
17528 z_range_test();
17529 maxmip_test();
17530 offscreen_test();
17531 ds_size_test();
17532 test_blend();
17533 shademode_test();
17534 srgbtexture_test();
17535 release_buffer_test();
17536 float_texture_test();
17537 g16r16_texture_test();
17538 pixelshader_blending_test();
17539 texture_transform_flags_test();
17540 autogen_mipmap_test();
17541 fixed_function_decl_test();
17542 conditional_np2_repeat_test();
17543 fixed_function_bumpmap_test();
17544 pointsize_test();
17545 tssargtemp_test();
17546 np2_stretch_rect_test();
17547 yuv_color_test();
17548 yuv_layout_test();
17549 zwriteenable_test();
17550 alphatest_test();
17551 viewport_test();
17552 test_constant_clamp_vs();
17553 test_compare_instructions();
17554 test_mova();
17555 loop_index_test();
17556 sincos_test();
17557 sgn_test();
17558 clip_planes_test();
17559 test_vshader_input();
17560 test_vshader_float16();
17561 stream_test();
17562 fog_with_shader_test();
17563 texbem_test();
17564 texdepth_test();
17565 texkill_test();
17566 x8l8v8u8_test();
17567 volume_v16u16_test();
17568 constant_clamp_ps_test();
17569 cnd_test();
17570 dp2add_ps_test();
17571 unbound_sampler_test();
17572 nested_loop_test();
17573 pretransformed_varying_test();
17574 vface_register_test();
17575 vpos_register_test();
17576 multiple_rendertargets_test();
17577 texop_test();
17578 texop_range_test();
17579 alphareplicate_test();
17580 dp3_alpha_test();
17581 depth_buffer_test();
17582 depth_buffer2_test();
17583 depth_blit_test();
17584 intz_test();
17585 shadow_test();
17586 fp_special_test();
17587 depth_bounds_test();
17588 srgbwrite_format_test();
17589 update_surface_test();
17590 multisample_get_rtdata_test();
17591 zenable_test();
17592 fog_special_test();
17593 volume_srgb_test();
17594 volume_dxt5_test();
17595 add_dirty_rect_test();
17596 multisampled_depth_buffer_test();
17597 resz_test();
17598 stencil_cull_test();
17599 test_per_stage_constant();
17600 test_3dc_formats();
17601 test_fog_interpolation();
17602 test_negative_fixedfunction_fog();
17603 test_position_index();
17604 test_table_fog_zw();