d3d9/tests: Use a separate device for release_buffer_test().
[wine.git] / dlls / d3d9 / tests / visual.c
blobbd2edbab683cd378832d6425519137661496dfd2
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 IDirect3DDevice9 *init_d3d9(void)
197 D3DADAPTER_IDENTIFIER9 identifier;
198 IDirect3DDevice9 *device;
199 IDirect3D9 *d3d9;
200 HWND window;
201 HRESULT hr;
203 if (!(d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
205 win_skip("could not create D3D9\n");
206 return NULL;
209 memset(&identifier, 0, sizeof(identifier));
210 hr = IDirect3D9_GetAdapterIdentifier(d3d9, 0, 0, &identifier);
211 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
212 trace("Driver string: \"%s\"\n", identifier.Driver);
213 trace("Description string: \"%s\"\n", identifier.Description);
214 /* Only Windows XP's default VGA driver should have an empty description */
215 ok(identifier.Description[0] != '\0' ||
216 broken(strcmp(identifier.Driver, "vga.dll") == 0),
217 "Empty driver description\n");
218 trace("Device name string: \"%s\"\n", identifier.DeviceName);
219 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
220 trace("Driver version %d.%d.%d.%d\n",
221 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
222 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
224 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
225 0, 0, 640, 480, NULL, NULL, NULL, NULL);
226 if ((device = create_device(d3d9, window, window, TRUE)))
227 return device;
229 DestroyWindow(window);
230 return NULL;
233 static void cleanup_device(IDirect3DDevice9 *device)
235 if (device)
237 D3DPRESENT_PARAMETERS present_parameters;
238 IDirect3DSwapChain9 *swapchain;
239 ULONG ref;
241 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
242 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
243 IDirect3DSwapChain9_Release(swapchain);
244 ref = IDirect3DDevice9_Release(device);
245 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
246 DestroyWindow(present_parameters.hDeviceWindow);
250 struct vertex
252 float x, y, z;
253 DWORD diffuse;
256 struct tvertex
258 float x, y, z, rhw;
259 DWORD diffuse;
262 struct nvertex
264 float x, y, z;
265 float nx, ny, nz;
266 DWORD diffuse;
269 static void lighting_test(IDirect3DDevice9 *device)
271 HRESULT hr;
272 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
273 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
274 DWORD color;
275 D3DMATERIAL9 material, old_material;
276 DWORD cop, carg;
277 DWORD old_colorwrite;
279 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
280 0.0f, 1.0f, 0.0f, 0.0f,
281 0.0f, 0.0f, 1.0f, 0.0f,
282 0.0f, 0.0f, 0.0f, 1.0f };
284 struct vertex unlitquad[] =
286 {-1.0f, -1.0f, 0.1f, 0xffff0000},
287 {-1.0f, 0.0f, 0.1f, 0xffff0000},
288 { 0.0f, 0.0f, 0.1f, 0xffff0000},
289 { 0.0f, -1.0f, 0.1f, 0xffff0000},
291 struct vertex litquad[] =
293 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
294 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
295 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
296 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
298 struct nvertex unlitnquad[] =
300 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
301 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
302 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
303 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
305 struct nvertex litnquad[] =
307 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
308 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
309 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
310 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
312 WORD Indices[] = {0, 1, 2, 2, 3, 0};
314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
315 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
317 /* Setup some states that may cause issues */
318 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
320 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
321 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
322 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
323 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
327 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
329 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
331 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
335 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
337 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
340 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
341 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
345 hr = IDirect3DDevice9_SetFVF(device, 0);
346 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
348 hr = IDirect3DDevice9_SetFVF(device, fvf);
349 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
351 hr = IDirect3DDevice9_BeginScene(device);
352 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
353 if(hr == D3D_OK)
355 /* No lights are defined... That means, lit vertices should be entirely black */
356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
357 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
358 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
359 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
360 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
363 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
364 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
365 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
366 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
368 hr = IDirect3DDevice9_SetFVF(device, nfvf);
369 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
372 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
373 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
374 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
375 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
378 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
379 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
380 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
381 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
383 hr = IDirect3DDevice9_EndScene(device);
384 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
387 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
388 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
389 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
390 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
391 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
392 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
393 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
394 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
396 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
398 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
399 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
400 memset(&material, 0, sizeof(material));
401 material.Diffuse.r = 0.0;
402 material.Diffuse.g = 0.0;
403 material.Diffuse.b = 0.0;
404 material.Diffuse.a = 1.0;
405 material.Ambient.r = 0.0;
406 material.Ambient.g = 0.0;
407 material.Ambient.b = 0.0;
408 material.Ambient.a = 0.0;
409 material.Specular.r = 0.0;
410 material.Specular.g = 0.0;
411 material.Specular.b = 0.0;
412 material.Specular.a = 0.0;
413 material.Emissive.r = 0.0;
414 material.Emissive.g = 0.0;
415 material.Emissive.b = 0.0;
416 material.Emissive.a = 0.0;
417 material.Power = 0.0;
418 hr = IDirect3DDevice9_SetMaterial(device, &material);
419 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
424 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
427 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
428 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
429 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
430 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
435 hr = IDirect3DDevice9_BeginScene(device);
436 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
437 if(SUCCEEDED(hr)) {
438 struct vertex lighting_test[] = {
439 {-1.0, -1.0, 0.1, 0x8000ff00},
440 { 1.0, -1.0, 0.1, 0x80000000},
441 {-1.0, 1.0, 0.1, 0x8000ff00},
442 { 1.0, 1.0, 0.1, 0x80000000}
444 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
445 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
447 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
449 hr = IDirect3DDevice9_EndScene(device);
450 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\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 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
458 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
460 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
464 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
466 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
467 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
468 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
469 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
470 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
473 static void clear_test(IDirect3DDevice9 *device)
475 /* Tests the correctness of clearing parameters */
476 HRESULT hr;
477 D3DRECT rect[2];
478 D3DRECT rect_negneg;
479 DWORD color;
480 D3DVIEWPORT9 old_vp, vp;
481 RECT scissor;
482 DWORD oldColorWrite;
483 BOOL invalid_clear_failed = FALSE;
485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
486 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
488 /* Positive x, negative y */
489 rect[0].x1 = 0;
490 rect[0].y1 = 480;
491 rect[0].x2 = 320;
492 rect[0].y2 = 240;
494 /* Positive x, positive y */
495 rect[1].x1 = 0;
496 rect[1].y1 = 0;
497 rect[1].x2 = 320;
498 rect[1].y2 = 240;
499 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
500 * returns D3D_OK, but ignores the rectangle silently
502 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
503 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
504 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
506 /* negative x, negative y */
507 rect_negneg.x1 = 640;
508 rect_negneg.y1 = 240;
509 rect_negneg.x2 = 320;
510 rect_negneg.y2 = 0;
511 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
512 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
513 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
515 color = getPixelColor(device, 160, 360); /* lower left quad */
516 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
517 color = getPixelColor(device, 160, 120); /* upper left quad */
518 if(invalid_clear_failed) {
519 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
520 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
521 } else {
522 /* If the negative rectangle was dropped silently, the correct ones are cleared */
523 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
525 color = getPixelColor(device, 480, 360); /* lower right quad */
526 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
527 color = getPixelColor(device, 480, 120); /* upper right quad */
528 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
530 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
532 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
533 * clear the red quad in the top left part of the render target. For some reason it
534 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
535 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
536 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
537 * pick some obvious value
539 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
540 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
542 /* Test how the viewport affects clears */
543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
544 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
545 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
546 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
548 vp.X = 160;
549 vp.Y = 120;
550 vp.Width = 160;
551 vp.Height = 120;
552 vp.MinZ = 0.0;
553 vp.MaxZ = 1.0;
554 hr = IDirect3DDevice9_SetViewport(device, &vp);
555 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
557 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559 vp.X = 320;
560 vp.Y = 240;
561 vp.Width = 320;
562 vp.Height = 240;
563 vp.MinZ = 0.0;
564 vp.MaxZ = 1.0;
565 hr = IDirect3DDevice9_SetViewport(device, &vp);
566 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
567 rect[0].x1 = 160;
568 rect[0].y1 = 120;
569 rect[0].x2 = 480;
570 rect[0].y2 = 360;
571 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
572 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
574 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
575 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
577 color = getPixelColor(device, 158, 118);
578 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
579 color = getPixelColor(device, 162, 118);
580 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
581 color = getPixelColor(device, 158, 122);
582 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
583 color = getPixelColor(device, 162, 122);
584 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
586 color = getPixelColor(device, 318, 238);
587 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
588 color = getPixelColor(device, 322, 238);
589 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
590 color = getPixelColor(device, 318, 242);
591 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
592 color = getPixelColor(device, 322, 242);
593 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
595 color = getPixelColor(device, 478, 358);
596 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
597 color = getPixelColor(device, 482, 358);
598 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
599 color = getPixelColor(device, 478, 362);
600 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
601 color = getPixelColor(device, 482, 362);
602 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
604 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
607 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
609 scissor.left = 160;
610 scissor.right = 480;
611 scissor.top = 120;
612 scissor.bottom = 360;
613 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
614 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
616 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
618 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
619 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
620 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
621 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
624 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
626 color = getPixelColor(device, 158, 118);
627 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
628 color = getPixelColor(device, 162, 118);
629 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
630 color = getPixelColor(device, 158, 122);
631 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
632 color = getPixelColor(device, 162, 122);
633 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
635 color = getPixelColor(device, 158, 358);
636 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
637 color = getPixelColor(device, 162, 358);
638 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
639 color = getPixelColor(device, 158, 358);
640 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
641 color = getPixelColor(device, 162, 362);
642 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
644 color = getPixelColor(device, 478, 118);
645 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
646 color = getPixelColor(device, 478, 122);
647 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
648 color = getPixelColor(device, 482, 122);
649 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
650 color = getPixelColor(device, 482, 358);
651 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
653 color = getPixelColor(device, 478, 358);
654 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
655 color = getPixelColor(device, 478, 362);
656 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
657 color = getPixelColor(device, 482, 358);
658 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
659 color = getPixelColor(device, 482, 362);
660 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
662 color = getPixelColor(device, 318, 238);
663 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
664 color = getPixelColor(device, 318, 242);
665 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
666 color = getPixelColor(device, 322, 238);
667 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
668 color = getPixelColor(device, 322, 242);
669 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
671 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
673 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
674 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
675 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
676 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
678 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
682 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
683 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
685 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
686 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
688 /* Colorwriteenable does not affect the clear */
689 color = getPixelColor(device, 320, 240);
690 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
692 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
695 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
697 rect[0].x1 = 0;
698 rect[0].y1 = 0;
699 rect[0].x2 = 640;
700 rect[0].y2 = 480;
701 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
702 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
704 color = getPixelColor(device, 320, 240);
705 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
706 "Clear with count = 0, rect != NULL has color %08x\n", color);
708 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
710 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
711 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
712 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
713 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
715 color = getPixelColor(device, 320, 240);
716 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
717 "Clear with count = 1, rect = NULL has color %08x\n", color);
719 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
722 static void color_fill_test(IDirect3DDevice9 *device)
724 HRESULT hr;
725 IDirect3DSurface9 *backbuffer = NULL;
726 IDirect3DSurface9 *rt_surface = NULL;
727 IDirect3DSurface9 *offscreen_surface = NULL;
728 DWORD fill_color, color;
730 /* Test ColorFill on a the backbuffer (should pass) */
731 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
732 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
733 if(backbuffer)
735 fill_color = 0x112233;
736 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
737 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
739 color = getPixelColor(device, 0, 0);
740 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
742 IDirect3DSurface9_Release(backbuffer);
745 /* Test ColorFill on a render target surface (should pass) */
746 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
747 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
748 if(rt_surface)
750 fill_color = 0x445566;
751 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
752 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
754 color = getPixelColorFromSurface(rt_surface, 0, 0);
755 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
757 IDirect3DSurface9_Release(rt_surface);
760 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
761 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
762 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
763 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
764 if(offscreen_surface)
766 fill_color = 0x778899;
767 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
768 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
770 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
771 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
773 IDirect3DSurface9_Release(offscreen_surface);
776 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
777 offscreen_surface = NULL;
778 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
779 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
780 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
781 if(offscreen_surface)
783 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
784 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
786 IDirect3DSurface9_Release(offscreen_surface);
791 * c7 mova ARGB mov ARGB
792 * -2.4 -2 0x00ffff00 -3 0x00ff0000
793 * -1.6 -2 0x00ffff00 -2 0x00ffff00
794 * -0.4 0 0x0000ffff -1 0x0000ff00
795 * 0.4 0 0x0000ffff 0 0x0000ffff
796 * 1.6 2 0x00ff00ff 1 0x000000ff
797 * 2.4 2 0x00ff00ff 2 0x00ff00ff
799 static void test_mova(void)
801 IDirect3DVertexDeclaration9 *vertex_declaration;
802 IDirect3DVertexShader9 *mova_shader;
803 IDirect3DVertexShader9 *mov_shader;
804 IDirect3DDevice9 *device;
805 unsigned int i, j;
806 IDirect3D9 *d3d;
807 ULONG refcount;
808 D3DCAPS9 caps;
809 HWND window;
810 HRESULT hr;
812 static const DWORD mova_test[] =
814 0xfffe0200, /* vs_2_0 */
815 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
816 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
817 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
818 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
819 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
820 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
821 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
822 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
823 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
824 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
825 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
826 0x0000ffff /* END */
828 static const DWORD mov_test[] =
830 0xfffe0101, /* vs_1_1 */
831 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
832 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
833 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
834 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
835 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
836 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
837 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
838 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
839 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
840 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
841 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
842 0x0000ffff /* END */
844 static const struct
846 float in[4];
847 DWORD out;
849 test_data[2][6] =
852 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
853 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
854 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
855 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
856 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
857 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
860 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
861 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
862 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
863 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
864 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
865 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
868 static const struct vec3 quad[] =
870 {-1.0f, -1.0f, 0.0f},
871 {-1.0f, 1.0f, 0.0f},
872 { 1.0f, -1.0f, 0.0f},
873 { 1.0f, 1.0f, 0.0f},
875 static const D3DVERTEXELEMENT9 decl_elements[] =
877 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
878 D3DDECL_END()
881 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
882 0, 0, 640, 480, NULL, NULL, NULL, NULL);
883 d3d = Direct3DCreate9(D3D_SDK_VERSION);
884 ok(!!d3d, "Failed to create a D3D object.\n");
885 if (!(device = create_device(d3d, window, window, TRUE)))
887 skip("Failed to create a D3D device, skipping tests.\n");
888 goto done;
891 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
892 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
893 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
895 skip("No vs_2_0 support, skipping tests.\n");
896 IDirect3DDevice9_Release(device);
897 goto done;
900 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
901 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
902 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
903 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
904 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
905 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
906 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
907 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
909 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
910 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
911 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
913 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
915 DWORD color;
917 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
918 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
920 hr = IDirect3DDevice9_BeginScene(device);
921 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
923 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
924 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
926 hr = IDirect3DDevice9_EndScene(device);
927 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
929 color = getPixelColor(device, 320, 240);
930 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
931 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
933 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
934 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
937 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
939 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
940 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
943 IDirect3DVertexDeclaration9_Release(vertex_declaration);
944 IDirect3DVertexShader9_Release(mova_shader);
945 IDirect3DVertexShader9_Release(mov_shader);
946 refcount = IDirect3DDevice9_Release(device);
947 ok(!refcount, "Device has %u references left.\n", refcount);
948 done:
949 IDirect3D9_Release(d3d);
950 DestroyWindow(window);
953 struct sVertex {
954 float x, y, z;
955 DWORD diffuse;
956 DWORD specular;
959 struct sVertexT {
960 float x, y, z, rhw;
961 DWORD diffuse;
962 DWORD specular;
965 static void fog_test(IDirect3DDevice9 *device)
967 HRESULT hr;
968 D3DCOLOR color;
969 float start = 0.0f, end = 1.0f;
970 D3DCAPS9 caps;
971 int i;
973 /* Gets full z based fog with linear fog, no fog with specular color */
974 struct sVertex untransformed_1[] = {
975 {-1, -1, 0.1f, 0xffff0000, 0xff000000 },
976 {-1, 0, 0.1f, 0xffff0000, 0xff000000 },
977 { 0, 0, 0.1f, 0xffff0000, 0xff000000 },
978 { 0, -1, 0.1f, 0xffff0000, 0xff000000 },
980 /* Ok, I am too lazy to deal with transform matrices */
981 struct sVertex untransformed_2[] = {
982 {-1, 0, 1.0f, 0xffff0000, 0xff000000 },
983 {-1, 1, 1.0f, 0xffff0000, 0xff000000 },
984 { 0, 1, 1.0f, 0xffff0000, 0xff000000 },
985 { 0, 0, 1.0f, 0xffff0000, 0xff000000 },
987 /* Untransformed ones. Give them a different diffuse color to make the test look
988 * nicer. It also makes making sure that they are drawn correctly easier.
990 struct sVertexT transformed_1[] = {
991 {320, 0, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
992 {640, 0, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
993 {640, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
994 {320, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
996 struct sVertexT transformed_2[] = {
997 {320, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
998 {640, 240, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
999 {640, 480, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
1000 {320, 480, 1.0f, 1.0f, 0xffffff00, 0xff000000 },
1002 struct vertex rev_fog_quads[] = {
1003 {-1.0, -1.0, 0.1, 0x000000ff},
1004 {-1.0, 0.0, 0.1, 0x000000ff},
1005 { 0.0, 0.0, 0.1, 0x000000ff},
1006 { 0.0, -1.0, 0.1, 0x000000ff},
1008 { 0.0, -1.0, 0.9, 0x000000ff},
1009 { 0.0, 0.0, 0.9, 0x000000ff},
1010 { 1.0, 0.0, 0.9, 0x000000ff},
1011 { 1.0, -1.0, 0.9, 0x000000ff},
1013 { 0.0, 0.0, 0.4, 0x000000ff},
1014 { 0.0, 1.0, 0.4, 0x000000ff},
1015 { 1.0, 1.0, 0.4, 0x000000ff},
1016 { 1.0, 0.0, 0.4, 0x000000ff},
1018 {-1.0, 0.0, 0.7, 0x000000ff},
1019 {-1.0, 1.0, 0.7, 0x000000ff},
1020 { 0.0, 1.0, 0.7, 0x000000ff},
1021 { 0.0, 0.0, 0.7, 0x000000ff},
1023 WORD Indices[] = {0, 1, 2, 2, 3, 0};
1025 const float ident_mat[16] =
1027 1.0f, 0.0f, 0.0f, 0.0f,
1028 0.0f, 1.0f, 0.0f, 0.0f,
1029 0.0f, 0.0f, 1.0f, 0.0f,
1030 0.0f, 0.0f, 0.0f, 1.0f
1032 const float world_mat1[16] =
1034 1.0f, 0.0f, 0.0f, 0.0f,
1035 0.0f, 1.0f, 0.0f, 0.0f,
1036 0.0f, 0.0f, 1.0f, 0.0f,
1037 0.0f, 0.0f, -0.5f, 1.0f
1039 const float world_mat2[16] =
1041 1.0f, 0.0f, 0.0f, 0.0f,
1042 0.0f, 1.0f, 0.0f, 0.0f,
1043 0.0f, 0.0f, 1.0f, 0.0f,
1044 0.0f, 0.0f, 1.0f, 1.0f
1046 const float proj_mat[16] =
1048 1.0f, 0.0f, 0.0f, 0.0f,
1049 0.0f, 1.0f, 0.0f, 0.0f,
1050 0.0f, 0.0f, 1.0f, 0.0f,
1051 0.0f, 0.0f, -1.0f, 1.0f
1054 const struct sVertex far_quad1[] =
1056 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1057 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1058 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1059 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1061 const struct sVertex far_quad2[] =
1063 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1064 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1065 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1066 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1069 memset(&caps, 0, sizeof(caps));
1070 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1071 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1073 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1075 /* Setup initial states: No lighting, fog on, fog color */
1076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1077 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1079 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1081 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1083 /* First test: Both table fog and vertex fog off */
1084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1085 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1087 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1089 /* Start = 0, end = 1. Should be default, but set them */
1090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1091 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1093 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1095 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1097 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1098 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1099 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
1100 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1101 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1102 sizeof(untransformed_1[0]));
1103 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1105 /* That makes it use the Z value */
1106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1107 ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
1108 /* Untransformed, vertex fog != none (or table fog != none):
1109 * Use the Z value as input into the equation
1111 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1112 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1113 sizeof(untransformed_2[0]));
1114 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1116 /* transformed verts */
1117 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1118 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1119 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1120 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1121 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1122 sizeof(transformed_1[0]));
1123 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1126 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1127 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
1128 * equation
1130 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1131 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
1132 sizeof(transformed_2[0]));
1133 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1135 hr = IDirect3DDevice9_EndScene(device);
1136 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1138 else
1140 ok(FALSE, "BeginScene failed\n");
1143 color = getPixelColor(device, 160, 360);
1144 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1145 color = getPixelColor(device, 160, 120);
1146 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1147 color = getPixelColor(device, 480, 120);
1148 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1149 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1151 color = getPixelColor(device, 480, 360);
1152 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1154 else
1156 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1157 * The settings above result in no fogging with vertex fog
1159 color = getPixelColor(device, 480, 120);
1160 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1161 trace("Info: Table fog not supported by this device\n");
1163 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1165 /* Now test the special case fogstart == fogend */
1166 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1167 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1169 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1171 start = 512;
1172 end = 512;
1173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1174 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1176 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1178 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1179 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1180 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1181 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1183 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1185 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1186 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1187 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1188 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1189 * color and has fixed fogstart and fogend.
1191 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1192 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1193 sizeof(untransformed_1[0]));
1194 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1195 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1196 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1197 sizeof(untransformed_2[0]));
1198 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1200 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1201 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1202 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1203 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1204 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1205 sizeof(transformed_1[0]));
1206 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1208 hr = IDirect3DDevice9_EndScene(device);
1209 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1211 else
1213 ok(FALSE, "BeginScene failed\n");
1215 color = getPixelColor(device, 160, 360);
1216 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1217 color = getPixelColor(device, 160, 120);
1218 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1219 color = getPixelColor(device, 480, 120);
1220 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1221 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1223 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1224 * but without shaders it seems to work everywhere
1226 end = 0.2;
1227 start = 0.8;
1228 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1229 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1231 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1232 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1233 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1235 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1236 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1237 * so skip this for now
1239 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1240 const char *mode = (i ? "table" : "vertex");
1241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1242 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1244 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1246 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1247 hr = IDirect3DDevice9_BeginScene(device);
1248 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1249 if(SUCCEEDED(hr)) {
1250 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1251 4, 5, 6, 6, 7, 4,
1252 8, 9, 10, 10, 11, 8,
1253 12, 13, 14, 14, 15, 12};
1255 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1256 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1257 sizeof(rev_fog_quads[0]));
1258 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1260 hr = IDirect3DDevice9_EndScene(device);
1261 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1263 color = getPixelColor(device, 160, 360);
1264 ok(color_match(color, 0x0000ff00, 1),
1265 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1267 color = getPixelColor(device, 160, 120);
1268 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1269 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1271 color = getPixelColor(device, 480, 120);
1272 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1273 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1275 color = getPixelColor(device, 480, 360);
1276 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1278 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1280 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1281 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1282 break;
1286 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1288 /* A simple fog + non-identity world matrix test */
1289 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat1);
1290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1292 start = 0.0;
1293 end = 1.0;
1294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1295 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1297 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1299 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1301 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1304 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1306 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1308 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1309 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1311 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1312 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1313 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1315 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1316 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1317 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1319 hr = IDirect3DDevice9_EndScene(device);
1320 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1322 else
1324 ok(FALSE, "BeginScene failed\n");
1327 color = getPixelColor(device, 160, 360);
1328 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1329 "Unfogged quad has color %08x\n", color);
1330 color = getPixelColor(device, 160, 120);
1331 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1332 "Fogged out quad has color %08x\n", color);
1334 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1336 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1337 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)world_mat2);
1338 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1339 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)proj_mat);
1340 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1342 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1343 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1345 if (IDirect3DDevice9_BeginScene(device) == D3D_OK)
1347 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1348 ok(hr == D3D_OK, "SetVertexShader returned %#08x\n", hr);
1350 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1351 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1352 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1354 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1355 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1356 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %#08x\n", hr);
1358 hr = IDirect3DDevice9_EndScene(device);
1359 ok(hr == D3D_OK, "EndScene returned %#08x\n", hr);
1361 else
1363 ok(FALSE, "BeginScene failed\n");
1366 color = getPixelColor(device, 160, 360);
1367 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1368 color = getPixelColor(device, 160, 120);
1369 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1370 "Fogged out quad has color %08x\n", color);
1372 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1374 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (const D3DMATRIX *)ident_mat);
1375 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1376 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (const D3DMATRIX *)ident_mat);
1377 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1379 else
1381 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1384 /* Test RANGEFOG vs FOGTABLEMODE */
1385 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1386 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1388 struct sVertex untransformed_3[] =
1390 {-1.0,-1.0, 0.4999f, 0xffff0000, 0xff000000 },
1391 {-1.0, 1.0, 0.4999f, 0xffff0000, 0xff000000 },
1392 { 1.0,-1.0, 0.4999f, 0xffff0000, 0xff000000 },
1393 { 1.0, 1.0, 0.4999f, 0xffff0000, 0xff000000 },
1396 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1397 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1399 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1402 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1404 /* z=0.4999, set the fogstart to 0.5 and fogend slightly higher. If range fog
1405 * is not used, the fog coordinate will be equal to fogstart and the quad not
1406 * fogged. If range fog is used the fog coordinate will be slightly higher and
1407 * the fog coordinate will be > fogend, so we get a fully fogged quad. The fog
1408 * is calculated per vertex and interpolated, so even the center of the screen
1409 * where the difference doesn't matter will be fogged, but check the corners in
1410 * case a d3d/gl implementation decides to calculate the fog factor per fragment */
1411 start = 0.5f;
1412 end = 0.50001f;
1413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1414 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1416 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1418 /* Table fog: Range fog is not used */
1419 hr = IDirect3DDevice9_BeginScene(device);
1420 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
1421 if (SUCCEEDED(hr))
1423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1424 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1425 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1426 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1427 hr = IDirect3DDevice9_EndScene(device);
1428 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1430 color = getPixelColor(device, 10, 10);
1431 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1432 color = getPixelColor(device, 630, 10);
1433 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1434 color = getPixelColor(device, 10, 470);
1435 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1436 color = getPixelColor(device, 630, 470);
1437 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
1439 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1440 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1442 /* Vertex fog: Rangefog is used */
1443 hr = IDirect3DDevice9_BeginScene(device);
1444 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP returned %#08x\n", hr);
1445 if (SUCCEEDED(hr))
1447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1448 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1450 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, untransformed_3, sizeof(*untransformed_3));
1452 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
1453 hr = IDirect3DDevice9_EndScene(device);
1454 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
1456 color = getPixelColor(device, 10, 10);
1457 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1458 "Rangefog with vertex fog returned color 0x%08x\n", color);
1459 color = getPixelColor(device, 630, 10);
1460 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1461 "Rangefog with vertex fog returned color 0x%08x\n", color);
1462 color = getPixelColor(device, 10, 470);
1463 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1464 "Rangefog with vertex fog returned color 0x%08x\n", color);
1465 color = getPixelColor(device, 630, 470);
1466 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1467 "Rangefog with vertex fog returned color 0x%08x\n", color);
1469 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1470 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
1472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
1473 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1475 else
1477 skip("Range fog or table fog not supported, skipping range fog tests\n");
1480 /* Turn off the fog master switch to avoid confusing other tests */
1481 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1482 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1484 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %08x\n", hr);
1485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1486 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1489 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1490 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1491 * regardless of the actual addressing mode set. The way this test works is
1492 * that we sample in one of the corners of the cubemap with filtering enabled,
1493 * and check the interpolated color. There are essentially two reasonable
1494 * things an implementation can do: Either pick one of the faces and
1495 * interpolate the edge texel with itself (i.e., clamp within the face), or
1496 * interpolate between the edge texels of the three involved faces. It should
1497 * never involve the border color or the other side (texcoord wrapping) of a
1498 * face in the interpolation. */
1499 static void test_cube_wrap(IDirect3DDevice9 *device)
1501 static const float quad[][6] = {
1502 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1503 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1504 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1505 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1508 static const D3DVERTEXELEMENT9 decl_elements[] = {
1509 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1510 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1511 D3DDECL_END()
1514 static const struct {
1515 D3DTEXTUREADDRESS mode;
1516 const char *name;
1517 } address_modes[] = {
1518 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1519 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1520 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1521 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1522 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1525 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1526 IDirect3DCubeTexture9 *texture = NULL;
1527 IDirect3DSurface9 *surface = NULL;
1528 IDirect3DSurface9 *face_surface;
1529 D3DLOCKED_RECT locked_rect;
1530 HRESULT hr;
1531 UINT x;
1532 INT y, face;
1534 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1535 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1536 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1537 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1539 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1540 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1541 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1543 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1544 D3DPOOL_DEFAULT, &texture, NULL);
1545 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1547 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1548 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1550 for (y = 0; y < 128; ++y)
1552 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1553 for (x = 0; x < 64; ++x)
1555 *ptr++ = 0xff0000ff;
1557 for (x = 64; x < 128; ++x)
1559 *ptr++ = 0xffff0000;
1563 hr = IDirect3DSurface9_UnlockRect(surface);
1564 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1566 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1567 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1569 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1570 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1572 IDirect3DSurface9_Release(face_surface);
1574 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1575 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1577 for (y = 0; y < 128; ++y)
1579 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1580 for (x = 0; x < 64; ++x)
1582 *ptr++ = 0xffff0000;
1584 for (x = 64; x < 128; ++x)
1586 *ptr++ = 0xff0000ff;
1590 hr = IDirect3DSurface9_UnlockRect(surface);
1591 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1593 /* Create cube faces */
1594 for (face = 1; face < 6; ++face)
1596 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1597 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1599 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1600 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1602 IDirect3DSurface9_Release(face_surface);
1605 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1606 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1608 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1609 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1610 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1611 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1612 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1613 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1616 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1618 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1620 DWORD color;
1622 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1623 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1624 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1625 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1627 hr = IDirect3DDevice9_BeginScene(device);
1628 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1631 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1633 hr = IDirect3DDevice9_EndScene(device);
1634 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1636 color = getPixelColor(device, 320, 240);
1637 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1638 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1639 color, address_modes[x].name);
1641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1642 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1644 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1645 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1648 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1649 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1651 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1652 IDirect3DCubeTexture9_Release(texture);
1653 IDirect3DSurface9_Release(surface);
1656 static void offscreen_test(IDirect3DDevice9 *device)
1658 HRESULT hr;
1659 IDirect3DTexture9 *offscreenTexture = NULL;
1660 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1661 DWORD color;
1663 static const float quad[][5] = {
1664 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1665 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1666 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1667 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1671 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1673 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1674 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1675 if(!offscreenTexture) {
1676 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1677 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1678 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1679 if(!offscreenTexture) {
1680 skip("Cannot create an offscreen render target\n");
1681 goto out;
1685 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1686 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1687 if(!backbuffer) {
1688 goto out;
1691 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1692 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1693 if(!offscreen) {
1694 goto out;
1697 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1698 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1700 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1701 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1703 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1704 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1705 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1706 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1707 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1709 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1711 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1712 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1713 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1714 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1715 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1717 /* Draw without textures - Should result in a white quad */
1718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1719 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1721 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1722 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1723 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1724 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1726 /* This time with the texture */
1727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1728 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1730 IDirect3DDevice9_EndScene(device);
1733 /* Center quad - should be white */
1734 color = getPixelColor(device, 320, 240);
1735 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1736 /* Some quad in the cleared part of the texture */
1737 color = getPixelColor(device, 170, 240);
1738 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1739 /* Part of the originally cleared back buffer */
1740 color = getPixelColor(device, 10, 10);
1741 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1742 if(0) {
1743 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1744 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1745 * the offscreen rendering mode this test would succeed or fail
1747 color = getPixelColor(device, 10, 470);
1748 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1751 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1753 out:
1754 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1755 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1757 /* restore things */
1758 if (backbuffer)
1760 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1761 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1762 IDirect3DSurface9_Release(backbuffer);
1764 if(offscreenTexture) {
1765 IDirect3DTexture9_Release(offscreenTexture);
1767 if(offscreen) {
1768 IDirect3DSurface9_Release(offscreen);
1772 /* This test tests fog in combination with shaders.
1773 * What's tested: linear fog (vertex and table) with pixel shader
1774 * linear table fog with non foggy vertex shader
1775 * vertex fog with foggy vertex shader, non-linear
1776 * fog with shader, non-linear fog with foggy shader,
1777 * linear table fog with foggy shader */
1778 static void fog_with_shader_test(void)
1780 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
1781 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
1782 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1783 IDirect3DDevice9 *device;
1784 unsigned int i, j;
1785 IDirect3D9 *d3d;
1786 ULONG refcount;
1787 D3DCAPS9 caps;
1788 DWORD color;
1789 HWND window;
1790 HRESULT hr;
1791 union
1793 float f;
1794 DWORD i;
1795 } start, end;
1797 /* basic vertex shader without fog computation ("non foggy") */
1798 static const DWORD vertex_shader_code1[] =
1800 0xfffe0101, /* vs_1_1 */
1801 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1802 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1803 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1804 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1805 0x0000ffff
1807 /* basic vertex shader with reversed fog computation ("foggy") */
1808 static const DWORD vertex_shader_code2[] =
1810 0xfffe0101, /* vs_1_1 */
1811 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1812 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1813 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1814 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1815 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1816 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1817 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1818 0x0000ffff
1820 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
1821 static const DWORD vertex_shader_code3[] =
1823 0xfffe0200, /* vs_2_0 */
1824 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1825 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1826 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1827 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1828 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1829 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1830 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1831 0x0000ffff
1833 /* basic pixel shader */
1834 static const DWORD pixel_shader_code[] =
1836 0xffff0101, /* ps_1_1 */
1837 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1838 0x0000ffff
1840 static const DWORD pixel_shader_code2[] =
1842 0xffff0200, /* ps_2_0 */
1843 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
1844 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
1845 0x0000ffff
1847 static struct vertex quad[] =
1849 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
1850 {-1.0f, 1.0f, 0.0f, 0xffff0000 },
1851 { 1.0f, -1.0f, 0.0f, 0xffff0000 },
1852 { 1.0f, 1.0f, 0.0f, 0xffff0000 },
1854 static const D3DVERTEXELEMENT9 decl_elements[] =
1856 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1857 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1858 D3DDECL_END()
1860 /* This reference data was collected on a nVidia GeForce 7600GS driver
1861 * version 84.19 DirectX version 9.0c on Windows XP. */
1862 static const struct test_data_t
1864 int vshader;
1865 int pshader;
1866 D3DFOGMODE vfog;
1867 D3DFOGMODE tfog;
1868 unsigned int color[11];
1870 test_data[] =
1872 /* only pixel shader: */
1873 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1874 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1875 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1876 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1877 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1878 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1879 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1880 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1881 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1882 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1883 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1884 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1885 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1886 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1887 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1889 /* vertex shader */
1890 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1891 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1892 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1893 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1894 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1895 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1896 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1897 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1898 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1900 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1901 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1902 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1903 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1904 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1905 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1907 /* vertex shader and pixel shader */
1908 /* The next 4 tests would read the fog coord output, but it isn't available.
1909 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1910 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1911 * These tests should be disabled if some other hardware behaves differently
1913 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1914 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1915 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1916 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1917 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1918 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1919 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1920 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1921 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1922 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1923 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1924 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1926 /* These use the Z coordinate with linear table fog */
1927 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1928 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1929 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1930 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1931 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1932 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1933 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1934 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1935 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1936 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1937 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1938 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1940 /* Non-linear table fog without fog coord */
1941 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1942 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1943 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1944 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1945 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1946 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1948 /* These tests fail on older Nvidia drivers */
1949 /* foggy vertex shader */
1950 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1951 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1952 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1953 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1954 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1955 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1956 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1957 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1958 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1959 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1960 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1961 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1963 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
1964 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1965 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1966 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
1967 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1968 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1969 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
1970 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1971 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1972 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1973 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1974 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1976 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1977 * all using the fixed fog-coord linear fog
1979 /* vs_1_1 with ps_1_1 */
1980 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1981 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1982 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1983 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1984 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1985 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1986 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1987 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1988 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1989 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1990 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1991 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1993 /* vs_2_0 with ps_1_1 */
1994 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
1995 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1996 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1997 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
1998 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1999 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2000 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2001 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2002 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2003 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2004 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2005 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2007 /* vs_1_1 with ps_2_0 */
2008 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2009 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2010 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2011 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2012 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2013 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2014 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2015 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2016 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2017 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2018 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2019 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2021 /* vs_2_0 with ps_2_0 */
2022 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2023 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2024 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2025 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2026 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2027 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2028 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2029 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2030 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2031 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2032 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2033 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2035 /* These use table fog. Here the shader-provided fog coordinate is
2036 * ignored and the z coordinate used instead
2038 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2039 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2040 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2041 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2042 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2043 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2044 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2045 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2046 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2048 static const D3DMATRIX identity =
2050 1.0f, 0.0f, 0.0f, 0.0f,
2051 0.0f, 1.0f, 0.0f, 0.0f,
2052 0.0f, 0.0f, 1.0f, 0.0f,
2053 0.0f, 0.0f, 0.0f, 1.0f,
2054 }}};
2056 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2057 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2058 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2059 ok(!!d3d, "Failed to create a D3D object.\n");
2060 if (!(device = create_device(d3d, window, window, TRUE)))
2062 skip("Failed to create a D3D device, skipping tests.\n");
2063 goto done;
2066 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2067 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2068 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2070 skip("No shader model 2 support, skipping tests.\n");
2071 IDirect3DDevice9_Release(device);
2072 goto done;
2075 /* NOTE: Changing these values will not affect the tests with foggy vertex
2076 * shader, as the values are hardcoded in the shader. */
2077 start.f = 0.1f;
2078 end.f = 0.9f;
2080 /* Some of the tests seem to depend on the projection matrix explicitly
2081 * being set to an identity matrix, even though that's the default.
2082 * (AMD Radeon HD 6310, Windows 7) */
2083 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2084 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2086 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2087 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2088 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2089 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2090 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2091 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2092 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2093 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2094 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2095 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2096 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2097 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2099 /* Setup initial states: No lighting, fog on, fog color */
2100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2101 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2103 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2105 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2106 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2107 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2110 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2112 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2114 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2116 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2118 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2120 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2122 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2123 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2124 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2125 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2127 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2129 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2131 for(j=0; j < 11; j++)
2133 /* Don't use the whole zrange to prevent rounding errors */
2134 quad[0].z = 0.001f + (float)j / 10.02f;
2135 quad[1].z = 0.001f + (float)j / 10.02f;
2136 quad[2].z = 0.001f + (float)j / 10.02f;
2137 quad[3].z = 0.001f + (float)j / 10.02f;
2139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2140 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2142 hr = IDirect3DDevice9_BeginScene(device);
2143 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2146 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2148 hr = IDirect3DDevice9_EndScene(device);
2149 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2151 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2152 color = getPixelColor(device, 128, 240);
2153 ok(color_match(color, test_data[i].color[j], 13),
2154 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2155 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2157 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2161 IDirect3DVertexShader9_Release(vertex_shader[1]);
2162 IDirect3DVertexShader9_Release(vertex_shader[2]);
2163 IDirect3DVertexShader9_Release(vertex_shader[3]);
2164 IDirect3DPixelShader9_Release(pixel_shader[1]);
2165 IDirect3DPixelShader9_Release(pixel_shader[2]);
2166 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2167 refcount = IDirect3DDevice9_Release(device);
2168 ok(!refcount, "Device has %u references left.\n", refcount);
2169 done:
2170 IDirect3D9_Release(d3d);
2171 DestroyWindow(window);
2174 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2175 unsigned int i, x, y;
2176 HRESULT hr;
2177 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2178 D3DLOCKED_RECT locked_rect;
2180 /* Generate the textures */
2181 for(i=0; i<2; i++)
2183 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2184 D3DPOOL_MANAGED, &texture[i], NULL);
2185 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2187 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2188 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2189 for (y = 0; y < 128; ++y)
2191 if(i)
2192 { /* Set up black texture with 2x2 texel white spot in the middle */
2193 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2194 for (x = 0; x < 128; ++x)
2196 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2199 else
2200 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2201 * (if multiplied with bumpenvmat)
2203 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2204 for (x = 0; x < 128; ++x)
2206 if(abs(x-64)>abs(y-64))
2208 if(x < 64)
2209 *ptr++ = 0xc000;
2210 else
2211 *ptr++ = 0x4000;
2213 else
2215 if(y < 64)
2216 *ptr++ = 0x0040;
2217 else
2218 *ptr++ = 0x00c0;
2223 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2224 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2226 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2227 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2229 /* Disable texture filtering */
2230 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2231 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2232 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2233 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2235 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2236 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2237 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2238 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2242 /* Test the behavior of the texbem instruction with normal 2D and projective
2243 * 2D textures. */
2244 static void texbem_test(void)
2246 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2247 /* Use asymmetric matrix to test loading. */
2248 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2249 IDirect3DPixelShader9 *pixel_shader = NULL;
2250 IDirect3DTexture9 *texture1, *texture2;
2251 IDirect3DTexture9 *texture = NULL;
2252 D3DLOCKED_RECT locked_rect;
2253 IDirect3DDevice9 *device;
2254 IDirect3D9 *d3d;
2255 ULONG refcount;
2256 D3DCAPS9 caps;
2257 DWORD color;
2258 HWND window;
2259 HRESULT hr;
2260 int i;
2262 static const DWORD pixel_shader_code[] =
2264 0xffff0101, /* ps_1_1*/
2265 0x00000042, 0xb00f0000, /* tex t0*/
2266 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2267 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2268 0x0000ffff
2270 static const DWORD double_texbem_code[] =
2272 0xffff0103, /* ps_1_3 */
2273 0x00000042, 0xb00f0000, /* tex t0 */
2274 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2275 0x00000042, 0xb00f0002, /* tex t2 */
2276 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2277 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2278 0x0000ffff /* end */
2280 static const float quad[][7] =
2282 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2283 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2284 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2285 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2287 static const float quad_proj[][9] =
2289 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2290 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2291 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2292 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2294 static const float double_quad[] =
2296 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2297 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2298 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2299 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2301 static const D3DVERTEXELEMENT9 decl_elements[][4] =
2304 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2305 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2306 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2307 D3DDECL_END()
2310 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2311 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2312 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2313 D3DDECL_END()
2317 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2318 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2319 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2320 ok(!!d3d, "Failed to create a D3D object.\n");
2321 if (!(device = create_device(d3d, window, window, TRUE)))
2323 skip("Failed to create a D3D device, skipping tests.\n");
2324 goto done;
2327 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2328 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2329 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2331 skip("No ps_1_1 support, skipping tests.\n");
2332 IDirect3DDevice9_Release(device);
2333 goto done;
2336 generate_bumpmap_textures(device);
2338 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2339 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2340 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2341 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2342 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2344 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2345 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2347 for(i=0; i<2; i++)
2349 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2350 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2352 if(i)
2354 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2355 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2358 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2359 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2360 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2361 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2363 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2364 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2365 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2366 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2368 hr = IDirect3DDevice9_BeginScene(device);
2369 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2371 if(!i)
2372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2373 else
2374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2375 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2377 hr = IDirect3DDevice9_EndScene(device);
2378 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2380 /* The Window 8 testbot (WARP) seems to use the transposed
2381 * D3DTSS_BUMPENVMAT matrix. */
2382 color = getPixelColor(device, 160, 240);
2383 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
2384 "Got unexpected color 0x%08x.\n", color);
2385 color = getPixelColor(device, 480, 240);
2386 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
2387 "Got unexpected color 0x%08x.\n", color);
2388 color = getPixelColor(device, 320, 120);
2389 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
2390 "Got unexpected color 0x%08x.\n", color);
2391 color = getPixelColor(device, 320, 360);
2392 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
2393 "Got unexpected color 0x%08x.\n", color);
2395 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2396 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2398 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2399 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2400 IDirect3DPixelShader9_Release(pixel_shader);
2402 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2403 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2404 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2407 /* clean up */
2408 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2409 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2411 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2412 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2414 for(i=0; i<2; i++)
2416 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
2417 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
2418 IDirect3DTexture9_Release(texture); /* For the GetTexture */
2419 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2420 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2421 IDirect3DTexture9_Release(texture);
2424 /* Test double texbem */
2425 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
2426 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2427 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
2428 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2429 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
2430 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
2431 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
2432 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2434 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
2435 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2436 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
2437 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
2439 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2440 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2442 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
2443 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2444 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
2445 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
2446 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
2447 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2450 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
2451 #define tex 0x00ff0000
2452 #define tex1 0x0000ff00
2453 #define origin 0x000000ff
2454 static const DWORD pixel_data[] = {
2455 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2456 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2457 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2458 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2459 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
2460 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2461 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2462 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
2464 #undef tex1
2465 #undef tex2
2466 #undef origin
2468 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
2469 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2470 for(i = 0; i < 8; i++) {
2471 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
2473 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
2474 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2477 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2478 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2479 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
2480 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2481 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
2482 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2483 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2484 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2485 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2486 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2487 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2488 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2490 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2491 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2492 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2493 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2494 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2495 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2496 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2497 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2498 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2499 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2501 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2502 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2503 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2504 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2505 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2506 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2507 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2508 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2509 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2510 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2512 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2513 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2514 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2515 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2516 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2517 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2518 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2519 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2520 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2521 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2522 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2523 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2524 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2525 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2526 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2527 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2529 hr = IDirect3DDevice9_BeginScene(device);
2530 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2532 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
2533 hr = IDirect3DDevice9_EndScene(device);
2534 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2535 /* The Window 8 testbot (WARP) seems to use the transposed
2536 * D3DTSS_BUMPENVMAT matrix. */
2537 color = getPixelColor(device, 320, 240);
2538 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
2539 "Got unexpected color 0x%08x.\n", color);
2541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2542 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2544 IDirect3DPixelShader9_Release(pixel_shader);
2545 IDirect3DTexture9_Release(texture);
2546 IDirect3DTexture9_Release(texture1);
2547 IDirect3DTexture9_Release(texture2);
2548 refcount = IDirect3DDevice9_Release(device);
2549 ok(!refcount, "Device has %u references left.\n", refcount);
2550 done:
2551 IDirect3D9_Release(d3d);
2552 DestroyWindow(window);
2555 static void z_range_test(IDirect3DDevice9 *device)
2557 static const struct vertex quad[] =
2559 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2560 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2561 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2562 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2564 static const struct vertex quad2[] =
2566 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2567 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2568 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2569 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2571 static const struct tvertex quad3[] =
2573 { 0.0f, 240.0f, 1.1f, 1.0f, 0xffffff00},
2574 { 0.0f, 480.0f, 1.1f, 1.0f, 0xffffff00},
2575 {640.0f, 240.0f, -1.1f, 1.0f, 0xffffff00},
2576 {640.0f, 480.0f, -1.1f, 1.0f, 0xffffff00},
2578 static const struct tvertex quad4[] =
2580 { 0.0f, 240.0f, 1.1f, 1.0f, 0xff00ff00},
2581 { 0.0f, 480.0f, 1.1f, 1.0f, 0xff00ff00},
2582 {640.0f, 240.0f, -1.1f, 1.0f, 0xff00ff00},
2583 {640.0f, 480.0f, -1.1f, 1.0f, 0xff00ff00},
2585 HRESULT hr;
2586 DWORD color;
2587 IDirect3DVertexShader9 *shader;
2588 D3DCAPS9 caps;
2589 static const DWORD shader_code[] =
2591 0xfffe0101, /* vs_1_1 */
2592 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2593 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2594 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2595 0x0000ffff /* end */
2597 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2598 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2600 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2601 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2603 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2604 * then call Present. Then clear the color buffer to make sure it has some defined content
2605 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2606 * by the depth value. */
2607 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2608 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2609 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2610 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2611 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2612 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2615 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2617 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2619 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2621 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2622 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2623 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2625 hr = IDirect3DDevice9_BeginScene(device);
2626 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2628 /* Test the untransformed vertex path */
2629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2630 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2632 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2634 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2636 /* Test the transformed vertex path */
2637 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2638 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2641 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2643 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2645 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2647 hr = IDirect3DDevice9_EndScene(device);
2648 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2650 /* Do not test the exact corner pixels, but go pretty close to them */
2652 /* Clipped because z > 1.0 */
2653 color = getPixelColor(device, 28, 238);
2654 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2655 color = getPixelColor(device, 28, 241);
2656 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2657 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2658 else
2659 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2661 /* Not clipped, > z buffer clear value(0.75).
2663 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2664 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2665 * equal to a stored depth buffer value of 0.5. */
2666 color = getPixelColor(device, 31, 238);
2667 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2668 color = getPixelColor(device, 31, 241);
2669 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2670 color = getPixelColor(device, 100, 238);
2671 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2672 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2673 color = getPixelColor(device, 100, 241);
2674 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2675 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2677 /* Not clipped, < z buffer clear value */
2678 color = getPixelColor(device, 104, 238);
2679 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2680 color = getPixelColor(device, 104, 241);
2681 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2682 color = getPixelColor(device, 318, 238);
2683 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2684 color = getPixelColor(device, 318, 241);
2685 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2687 /* Clipped because z < 0.0 */
2688 color = getPixelColor(device, 321, 238);
2689 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2690 color = getPixelColor(device, 321, 241);
2691 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2692 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2693 else
2694 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2696 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2697 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2699 /* Test the shader path */
2700 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2702 skip("Vertex shaders not supported\n");
2703 goto out;
2705 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2706 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2708 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2709 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2711 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2712 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2713 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2714 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2716 hr = IDirect3DDevice9_BeginScene(device);
2717 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2719 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
2720 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2722 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2725 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2726 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
2727 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2729 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2731 hr = IDirect3DDevice9_EndScene(device);
2732 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2734 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2735 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2737 IDirect3DVertexShader9_Release(shader);
2739 /* 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);
2743 /* 1.0 < z < 0.75 */
2744 color = getPixelColor(device, 31, 238);
2745 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2746 color = getPixelColor(device, 100, 238);
2747 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2748 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2750 /* 0.75 < z < 0.0 */
2751 color = getPixelColor(device, 104, 238);
2752 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2753 color = getPixelColor(device, 318, 238);
2754 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2756 /* 0.0 < z */
2757 color = getPixelColor(device, 321, 238);
2758 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2760 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2761 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2763 out:
2764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2765 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
2766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2767 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
2768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2769 ok(SUCCEEDED(hr), "Failed to enable z writes, hr %#x.\n", hr);
2772 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
2774 D3DSURFACE_DESC desc;
2775 D3DLOCKED_RECT l;
2776 HRESULT hr;
2777 unsigned int x, y;
2778 DWORD *mem;
2780 memset(&desc, 0, sizeof(desc));
2781 memset(&l, 0, sizeof(l));
2782 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2783 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2784 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
2785 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2786 if(FAILED(hr)) return;
2788 for(y = 0; y < desc.Height; y++)
2790 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2791 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2793 mem[x] = color;
2796 hr = IDirect3DSurface9_UnlockRect(surface);
2797 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2800 /* This tests a variety of possible StretchRect() situations */
2801 static void stretchrect_test(IDirect3DDevice9 *device)
2803 HRESULT hr;
2804 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2805 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2806 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2807 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2808 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2809 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2810 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2811 IDirect3DSurface9 *orig_rt = NULL;
2812 IDirect3DSurface9 *backbuffer = NULL;
2813 DWORD color;
2815 RECT src_rect64 = {0, 0, 64, 64};
2816 RECT src_rect64_flipy = {0, 64, 64, 0};
2817 RECT dst_rect64 = {0, 0, 64, 64};
2818 RECT dst_rect64_flipy = {0, 64, 64, 0};
2820 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2821 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2822 if(!orig_rt) {
2823 goto out;
2826 /* Create our temporary surfaces in system memory */
2827 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2828 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2829 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2830 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2832 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2833 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2834 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2835 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2836 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2837 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2838 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2840 /* Create render target surfaces */
2841 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2842 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2843 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2844 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2845 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2846 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2847 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2848 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2850 /* Create render target textures */
2851 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2852 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2853 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2854 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2855 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2856 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2857 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2858 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2859 if (tex_rt32) {
2860 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2861 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2863 if (tex_rt64) {
2864 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2865 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2867 if (tex_rt_dest64) {
2868 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2869 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2871 if (tex_rt_dest640_480) {
2872 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2873 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2876 /* Create regular textures in D3DPOOL_DEFAULT */
2877 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2878 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2879 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2880 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2881 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2882 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2883 if (tex32) {
2884 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2885 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2887 if (tex64) {
2888 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2889 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2891 if (tex_dest64) {
2892 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2893 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2896 /*********************************************************************
2897 * Tests for when the source parameter is an offscreen plain surface *
2898 *********************************************************************/
2900 /* Fill the offscreen 64x64 surface with green */
2901 if (surf_offscreen64)
2902 fill_surface(surf_offscreen64, 0xff00ff00, 0);
2904 /* offscreenplain ==> offscreenplain, same size */
2905 if(surf_offscreen64 && surf_offscreen_dest64) {
2906 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2907 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2909 if (hr == D3D_OK) {
2910 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2911 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2914 /* Blit without scaling */
2915 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2916 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2918 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2919 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2920 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2922 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2923 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2924 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2927 /* offscreenplain ==> rendertarget texture, same size */
2928 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2929 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2930 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2932 /* We can't lock rendertarget textures, so copy to our temp surface first */
2933 if (hr == D3D_OK) {
2934 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2935 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2938 if (hr == D3D_OK) {
2939 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2940 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2943 /* Blit without scaling */
2944 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2945 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2947 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2948 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2949 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2951 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2952 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2953 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2956 /* offscreenplain ==> rendertarget surface, same size */
2957 if(surf_offscreen64 && surf_rt_dest64) {
2958 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2959 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2961 if (hr == D3D_OK) {
2962 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2963 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2966 /* Blit without scaling */
2967 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2968 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2970 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2971 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2972 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2974 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2975 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2976 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2979 /* offscreenplain ==> texture, same size (should fail) */
2980 if(surf_offscreen64 && surf_tex_dest64) {
2981 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2982 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2985 /* Fill the smaller offscreen surface with red */
2986 fill_surface(surf_offscreen32, 0xffff0000, 0);
2988 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2989 if(surf_offscreen32 && surf_offscreen64) {
2990 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2991 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2994 /* offscreenplain ==> rendertarget texture, scaling */
2995 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2996 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2997 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2999 /* We can't lock rendertarget textures, so copy to our temp surface first */
3000 if (hr == D3D_OK) {
3001 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3002 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3005 if (hr == D3D_OK) {
3006 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3007 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3011 /* offscreenplain ==> rendertarget surface, scaling */
3012 if(surf_offscreen32 && surf_rt_dest64) {
3013 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
3014 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3016 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3017 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3020 /* offscreenplain ==> texture, scaling (should fail) */
3021 if(surf_offscreen32 && surf_tex_dest64) {
3022 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
3023 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3026 /************************************************************
3027 * Tests for when the source parameter is a regular texture *
3028 ************************************************************/
3030 /* Fill the surface of the regular texture with blue */
3031 if (surf_tex64 && surf_temp64) {
3032 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
3033 fill_surface(surf_temp64, 0xff0000ff, 0);
3034 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3035 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3038 /* texture ==> offscreenplain, same size */
3039 if(surf_tex64 && surf_offscreen64) {
3040 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
3041 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3044 /* texture ==> rendertarget texture, same size */
3045 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
3046 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
3047 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3049 /* We can't lock rendertarget textures, so copy to our temp surface first */
3050 if (hr == D3D_OK) {
3051 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3052 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3055 if (hr == D3D_OK) {
3056 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3057 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
3060 /* Blit without scaling */
3061 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3062 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3064 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3065 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3066 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3068 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3069 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3070 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3073 /* texture ==> rendertarget surface, same size */
3074 if(surf_tex64 && surf_rt_dest64) {
3075 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
3076 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3078 if (hr == D3D_OK) {
3079 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3080 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
3083 /* Blit without scaling */
3084 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3085 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3087 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3088 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3089 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3091 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3092 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3093 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3096 /* texture ==> texture, same size (should fail) */
3097 if(surf_tex64 && surf_tex_dest64) {
3098 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
3099 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3102 /* Fill the surface of the smaller regular texture with red */
3103 if (surf_tex32 && surf_temp32) {
3104 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
3105 fill_surface(surf_temp32, 0xffff0000, 0);
3106 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3107 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3110 /* texture ==> offscreenplain, scaling (should fail) */
3111 if(surf_tex32 && surf_offscreen64) {
3112 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
3113 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3116 /* texture ==> rendertarget texture, scaling */
3117 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
3118 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
3119 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3121 /* We can't lock rendertarget textures, so copy to our temp surface first */
3122 if (hr == D3D_OK) {
3123 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3124 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3127 if (hr == D3D_OK) {
3128 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3129 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3133 /* texture ==> rendertarget surface, scaling */
3134 if(surf_tex32 && surf_rt_dest64) {
3135 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
3136 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3138 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3139 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3142 /* texture ==> texture, scaling (should fail) */
3143 if(surf_tex32 && surf_tex_dest64) {
3144 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
3145 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3148 /*****************************************************************
3149 * Tests for when the source parameter is a rendertarget texture *
3150 *****************************************************************/
3152 /* Fill the surface of the rendertarget texture with white */
3153 if (surf_tex_rt64 && surf_temp64) {
3154 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3155 fill_surface(surf_temp64, 0xffffffff, 0);
3156 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3157 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3160 /* rendertarget texture ==> offscreenplain, same size */
3161 if(surf_tex_rt64 && surf_offscreen64) {
3162 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
3163 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3166 /* rendertarget texture ==> rendertarget texture, same size */
3167 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3168 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3169 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3171 /* We can't lock rendertarget textures, so copy to our temp surface first */
3172 if (hr == D3D_OK) {
3173 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3174 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3177 if (hr == D3D_OK) {
3178 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3179 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3182 /* Blit without scaling */
3183 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3184 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3186 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3187 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3188 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3190 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3191 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3192 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3195 /* rendertarget texture ==> rendertarget surface, same size */
3196 if(surf_tex_rt64 && surf_rt_dest64) {
3197 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
3198 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3200 if (hr == D3D_OK) {
3201 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3202 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
3205 /* Blit without scaling */
3206 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3207 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3209 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3210 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
3211 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3213 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3214 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3215 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3218 /* rendertarget texture ==> texture, same size (should fail) */
3219 if(surf_tex_rt64 && surf_tex_dest64) {
3220 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
3221 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3224 /* Fill the surface of the smaller rendertarget texture with red */
3225 if (surf_tex_rt32 && surf_temp32) {
3226 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
3227 fill_surface(surf_temp32, 0xffff0000, 0);
3228 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3229 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
3232 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
3233 if(surf_tex_rt32 && surf_offscreen64) {
3234 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
3235 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3238 /* rendertarget texture ==> rendertarget texture, scaling */
3239 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3240 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3241 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3243 /* We can't lock rendertarget textures, so copy to our temp surface first */
3244 if (hr == D3D_OK) {
3245 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3246 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3249 if (hr == D3D_OK) {
3250 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3251 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3255 /* rendertarget texture ==> rendertarget surface, scaling */
3256 if(surf_tex_rt32 && surf_rt_dest64) {
3257 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
3258 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3260 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3261 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3264 /* rendertarget texture ==> texture, scaling (should fail) */
3265 if(surf_tex_rt32 && surf_tex_dest64) {
3266 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
3267 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3270 /*****************************************************************
3271 * Tests for when the source parameter is a rendertarget surface *
3272 *****************************************************************/
3274 /* Fill the surface of the rendertarget surface with black */
3275 if (surf_rt64)
3276 fill_surface(surf_rt64, 0xff000000, 0);
3278 /* rendertarget texture ==> offscreenplain, same size */
3279 if(surf_rt64 && surf_offscreen64) {
3280 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
3281 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3284 /* rendertarget surface ==> rendertarget texture, same size */
3285 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
3286 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
3287 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3289 /* We can't lock rendertarget textures, so copy to our temp surface first */
3290 if (hr == D3D_OK) {
3291 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3292 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3295 if (hr == D3D_OK) {
3296 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3297 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3300 /* Blit without scaling */
3301 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
3302 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3304 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3305 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
3306 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3308 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3309 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
3310 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3313 /* rendertarget surface ==> rendertarget surface, same size */
3314 if(surf_rt64 && surf_rt_dest64) {
3315 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
3316 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3318 if (hr == D3D_OK) {
3319 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3320 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
3323 /* Blit without scaling */
3324 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
3325 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3327 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3328 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
3329 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3331 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3332 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
3333 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3336 /* rendertarget surface ==> texture, same size (should fail) */
3337 if(surf_rt64 && surf_tex_dest64) {
3338 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
3339 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3342 /* Fill the surface of the smaller rendertarget texture with red */
3343 if (surf_rt32)
3344 fill_surface(surf_rt32, 0xffff0000, 0);
3346 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
3347 if(surf_rt32 && surf_offscreen64) {
3348 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
3349 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3352 /* rendertarget surface ==> rendertarget texture, scaling */
3353 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
3354 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
3355 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3357 /* We can't lock rendertarget textures, so copy to our temp surface first */
3358 if (hr == D3D_OK) {
3359 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3360 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
3363 if (hr == D3D_OK) {
3364 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3365 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3369 /* rendertarget surface ==> rendertarget surface, scaling */
3370 if(surf_rt32 && surf_rt_dest64) {
3371 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
3372 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3374 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3375 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
3378 /* rendertarget surface ==> texture, scaling (should fail) */
3379 if(surf_rt32 && surf_tex_dest64) {
3380 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
3381 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3384 /* backbuffer ==> surface tests (no scaling) */
3385 if(backbuffer && surf_tex_rt_dest640_480)
3387 RECT src_rect = {0, 0, 640, 480};
3388 RECT src_rect_flipy = {0, 480, 640, 0};
3389 RECT dst_rect = {0, 0, 640, 480};
3390 RECT dst_rect_flipy = {0, 480, 640, 0};
3392 /* Blit with NULL rectangles */
3393 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
3394 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
3396 /* Blit without scaling */
3397 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
3398 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
3400 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
3401 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
3402 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3404 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
3405 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
3406 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
3409 /* TODO: Test format conversions */
3412 out:
3413 /* Clean up */
3414 if (backbuffer)
3415 IDirect3DSurface9_Release(backbuffer);
3416 if (surf_rt32)
3417 IDirect3DSurface9_Release(surf_rt32);
3418 if (surf_rt64)
3419 IDirect3DSurface9_Release(surf_rt64);
3420 if (surf_rt_dest64)
3421 IDirect3DSurface9_Release(surf_rt_dest64);
3422 if (surf_temp32)
3423 IDirect3DSurface9_Release(surf_temp32);
3424 if (surf_temp64)
3425 IDirect3DSurface9_Release(surf_temp64);
3426 if (surf_offscreen32)
3427 IDirect3DSurface9_Release(surf_offscreen32);
3428 if (surf_offscreen64)
3429 IDirect3DSurface9_Release(surf_offscreen64);
3430 if (surf_offscreen_dest64)
3431 IDirect3DSurface9_Release(surf_offscreen_dest64);
3433 if (tex_rt32) {
3434 if (surf_tex_rt32)
3435 IDirect3DSurface9_Release(surf_tex_rt32);
3436 IDirect3DTexture9_Release(tex_rt32);
3438 if (tex_rt64) {
3439 if (surf_tex_rt64)
3440 IDirect3DSurface9_Release(surf_tex_rt64);
3441 IDirect3DTexture9_Release(tex_rt64);
3443 if (tex_rt_dest64) {
3444 if (surf_tex_rt_dest64)
3445 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3446 IDirect3DTexture9_Release(tex_rt_dest64);
3448 if (tex_rt_dest640_480) {
3449 if (surf_tex_rt_dest640_480)
3450 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3451 IDirect3DTexture9_Release(tex_rt_dest640_480);
3453 if (tex32) {
3454 if (surf_tex32)
3455 IDirect3DSurface9_Release(surf_tex32);
3456 IDirect3DTexture9_Release(tex32);
3458 if (tex64) {
3459 if (surf_tex64)
3460 IDirect3DSurface9_Release(surf_tex64);
3461 IDirect3DTexture9_Release(tex64);
3463 if (tex_dest64) {
3464 if (surf_tex_dest64)
3465 IDirect3DSurface9_Release(surf_tex_dest64);
3466 IDirect3DTexture9_Release(tex_dest64);
3469 if (orig_rt) {
3470 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3471 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3472 IDirect3DSurface9_Release(orig_rt);
3476 static void maxmip_test(IDirect3DDevice9 *device)
3478 IDirect3DTexture9 *texture = NULL;
3479 IDirect3DSurface9 *surface = NULL;
3480 HRESULT hr;
3481 DWORD color;
3482 static const struct
3484 struct
3486 float x, y, z;
3487 float s, t;
3489 v[4];
3491 quads[] =
3494 {-1.0, -1.0, 0.0, 0.0, 0.0},
3495 {-1.0, 0.0, 0.0, 0.0, 1.0},
3496 { 0.0, -1.0, 0.0, 1.0, 0.0},
3497 { 0.0, 0.0, 0.0, 1.0, 1.0},
3500 { 0.0, -1.0, 0.0, 0.0, 0.0},
3501 { 0.0, 0.0, 0.0, 0.0, 1.0},
3502 { 1.0, -1.0, 0.0, 1.0, 0.0},
3503 { 1.0, 0.0, 0.0, 1.0, 1.0},
3506 { 0.0, 0.0, 0.0, 0.0, 0.0},
3507 { 0.0, 1.0, 0.0, 0.0, 1.0},
3508 { 1.0, 0.0, 0.0, 1.0, 0.0},
3509 { 1.0, 1.0, 0.0, 1.0, 1.0},
3512 {-1.0, 0.0, 0.0, 0.0, 0.0},
3513 {-1.0, 1.0, 0.0, 0.0, 1.0},
3514 { 0.0, 0.0, 0.0, 1.0, 0.0},
3515 { 0.0, 1.0, 0.0, 1.0, 1.0},
3519 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3520 &texture, NULL);
3521 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3522 if(!texture)
3524 skip("Failed to create test texture\n");
3525 return;
3528 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3529 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3530 fill_surface(surface, 0xffff0000, 0);
3531 IDirect3DSurface9_Release(surface);
3532 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3533 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3534 fill_surface(surface, 0xff00ff00, 0);
3535 IDirect3DSurface9_Release(surface);
3536 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3537 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3538 fill_surface(surface, 0xff0000ff, 0);
3539 IDirect3DSurface9_Release(surface);
3541 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3542 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3543 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3544 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3546 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3547 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3550 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3552 hr = IDirect3DDevice9_BeginScene(device);
3553 if(SUCCEEDED(hr))
3555 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3556 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3558 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3560 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3561 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3563 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3565 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3566 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3568 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3570 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3571 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3573 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3574 hr = IDirect3DDevice9_EndScene(device);
3575 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3578 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3579 color = getPixelColor(device, 160, 360);
3580 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3581 color = getPixelColor(device, 480, 360);
3582 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3583 color = getPixelColor(device, 480, 120);
3584 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3585 color = getPixelColor(device, 160, 120);
3586 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3587 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3588 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3590 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3591 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3593 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3594 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3596 hr = IDirect3DDevice9_BeginScene(device);
3597 if(SUCCEEDED(hr))
3599 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3600 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3601 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3602 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3604 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3605 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3609 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3610 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3612 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3614 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3615 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3617 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3618 hr = IDirect3DDevice9_EndScene(device);
3619 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3622 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3623 * level 3 (> levels in texture) samples from the highest level in the
3624 * texture (level 2). */
3625 color = getPixelColor(device, 160, 360);
3626 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3627 color = getPixelColor(device, 480, 360);
3628 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3629 color = getPixelColor(device, 480, 120);
3630 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3631 color = getPixelColor(device, 160, 120);
3632 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3633 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3634 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3636 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3637 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3639 hr = IDirect3DDevice9_BeginScene(device);
3640 if(SUCCEEDED(hr))
3642 DWORD ret;
3644 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3645 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3646 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3647 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3648 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3649 ret = IDirect3DTexture9_SetLOD(texture, 1);
3650 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3652 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3654 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3655 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3656 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3657 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3658 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3659 ret = IDirect3DTexture9_SetLOD(texture, 2);
3660 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3661 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3662 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3664 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3665 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3666 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3667 ret = IDirect3DTexture9_SetLOD(texture, 1);
3668 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3670 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3672 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3673 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3675 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3676 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3677 ret = IDirect3DTexture9_SetLOD(texture, 1);
3678 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3680 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3681 hr = IDirect3DDevice9_EndScene(device);
3682 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3685 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3686 * level 3 (> levels in texture) samples from the highest level in the
3687 * texture (level 2). */
3688 color = getPixelColor(device, 160, 360);
3689 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3690 color = getPixelColor(device, 480, 360);
3691 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3692 color = getPixelColor(device, 480, 120);
3693 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3694 color = getPixelColor(device, 160, 120);
3695 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3697 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3698 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3700 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3701 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3702 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3703 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3704 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3705 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3706 IDirect3DTexture9_Release(texture);
3709 static void release_buffer_test(void)
3711 IDirect3DVertexBuffer9 *vb;
3712 IDirect3DIndexBuffer9 *ib;
3713 IDirect3DDevice9 *device;
3714 IDirect3D9 *d3d;
3715 D3DCOLOR color;
3716 ULONG refcount;
3717 HWND window;
3718 HRESULT hr;
3719 BYTE *data;
3720 LONG ref;
3722 static const short indices[] = {3, 4, 5};
3723 static const struct vertex quad[] =
3725 {-1.0f, -1.0f, 0.1f, 0xffff0000},
3726 {-1.0f, 1.0f, 0.1f, 0xffff0000},
3727 { 1.0f, 1.0f, 0.1f, 0xffff0000},
3729 {-1.0f, -1.0f, 0.1f, 0xff00ff00},
3730 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
3731 { 1.0f, 1.0f, 0.1f, 0xff00ff00},
3734 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3735 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3736 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3737 ok(!!d3d, "Failed to create a D3D object.\n");
3738 if (!(device = create_device(d3d, window, window, TRUE)))
3740 skip("Failed to create a D3D device, skipping tests.\n");
3741 goto done;
3744 /* Index and vertex buffers should always be creatable */
3745 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
3746 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
3747 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3748 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3749 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3750 memcpy(data, quad, sizeof(quad));
3751 hr = IDirect3DVertexBuffer9_Unlock(vb);
3752 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3754 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
3755 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3756 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
3757 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3758 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3759 memcpy(data, indices, sizeof(indices));
3760 hr = IDirect3DIndexBuffer9_Unlock(ib);
3761 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3763 hr = IDirect3DDevice9_SetIndices(device, ib);
3764 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3765 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3766 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3767 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3768 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3770 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3772 /* Now destroy the bound index buffer and draw again */
3773 ref = IDirect3DIndexBuffer9_Release(ib);
3774 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3779 hr = IDirect3DDevice9_BeginScene(device);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3781 if(SUCCEEDED(hr))
3783 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3784 * making assumptions about the indices or vertices
3786 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3787 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3788 hr = IDirect3DDevice9_EndScene(device);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3792 color = getPixelColor(device, 160, 120);
3793 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
3794 color = getPixelColor(device, 480, 360);
3795 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
3797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3800 /* Index buffer was already destroyed as part of the test */
3801 IDirect3DVertexBuffer9_Release(vb);
3802 refcount = IDirect3DDevice9_Release(device);
3803 ok(!refcount, "Device has %u references left.\n", refcount);
3804 done:
3805 IDirect3D9_Release(d3d);
3806 DestroyWindow(window);
3809 static void float_texture_test(void)
3811 IDirect3DTexture9 *texture;
3812 IDirect3DDevice9 *device;
3813 D3DLOCKED_RECT lr;
3814 IDirect3D9 *d3d;
3815 ULONG refcount;
3816 float *data;
3817 DWORD color;
3818 HWND window;
3819 HRESULT hr;
3821 static const float quad[] =
3823 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
3824 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
3825 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
3826 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
3829 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3830 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3831 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3832 ok(!!d3d, "Failed to create a D3D object.\n");
3833 if (!(device = create_device(d3d, window, window, TRUE)))
3835 skip("Failed to create a D3D device, skipping tests.\n");
3836 goto done;
3839 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
3840 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
3842 skip("D3DFMT_R32F textures not supported\n");
3843 IDirect3DDevice9_Release(device);
3844 goto done;
3847 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
3848 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3850 memset(&lr, 0, sizeof(lr));
3851 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3852 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3853 data = lr.pBits;
3854 *data = 0.0;
3855 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3856 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3859 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3860 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
3861 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3863 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3864 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3866 hr = IDirect3DDevice9_BeginScene(device);
3867 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3868 if(SUCCEEDED(hr))
3870 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3871 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3874 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3876 hr = IDirect3DDevice9_EndScene(device);
3877 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3880 color = getPixelColor(device, 240, 320);
3881 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
3883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3884 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3886 IDirect3DTexture9_Release(texture);
3887 refcount = IDirect3DDevice9_Release(device);
3888 ok(!refcount, "Device has %u references left.\n", refcount);
3889 done:
3890 IDirect3D9_Release(d3d);
3891 DestroyWindow(window);
3894 static void g16r16_texture_test(void)
3896 IDirect3DTexture9 *texture;
3897 IDirect3DDevice9 *device;
3898 D3DLOCKED_RECT lr;
3899 IDirect3D9 *d3d;
3900 ULONG refcount;
3901 DWORD *data;
3902 DWORD color;
3903 HWND window;
3904 HRESULT hr;
3906 static const float quad[] =
3908 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
3909 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
3910 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
3911 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
3914 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3915 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3916 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3917 ok(!!d3d, "Failed to create a D3D object.\n");
3918 if (!(device = create_device(d3d, window, window, TRUE)))
3920 skip("Failed to create a D3D device, skipping tests.\n");
3921 goto done;
3924 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
3925 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
3927 skip("D3DFMT_G16R16 textures not supported\n");
3928 IDirect3DDevice9_Release(device);
3929 goto done;
3932 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
3933 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3935 memset(&lr, 0, sizeof(lr));
3936 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3937 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3938 data = lr.pBits;
3939 *data = 0x0f00f000;
3940 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3941 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3944 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3945 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
3946 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3948 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3949 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3951 hr = IDirect3DDevice9_BeginScene(device);
3952 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3953 if(SUCCEEDED(hr))
3955 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3956 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3959 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3961 hr = IDirect3DDevice9_EndScene(device);
3962 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3965 color = getPixelColor(device, 240, 320);
3966 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3967 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3969 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3970 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3972 IDirect3DTexture9_Release(texture);
3973 refcount = IDirect3DDevice9_Release(device);
3974 ok(!refcount, "Device has %u references left.\n", refcount);
3975 done:
3976 IDirect3D9_Release(d3d);
3977 DestroyWindow(window);
3980 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3982 LONG x_coords[2][2] =
3984 {r.left - 1, r.left + 1},
3985 {r.right + 1, r.right - 1},
3987 LONG y_coords[2][2] =
3989 {r.top - 1, r.top + 1},
3990 {r.bottom + 1, r.bottom - 1}
3992 unsigned int i, j, x_side, y_side;
3994 for (i = 0; i < 2; ++i)
3996 for (j = 0; j < 2; ++j)
3998 for (x_side = 0; x_side < 2; ++x_side)
4000 for (y_side = 0; y_side < 2; ++y_side)
4002 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4003 DWORD color;
4004 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4006 color = getPixelColor(device, x, y);
4007 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4008 message, x, y, color, expected);
4015 struct projected_textures_test_run
4017 const char *message;
4018 DWORD flags;
4019 IDirect3DVertexDeclaration9 *decl;
4020 BOOL vs, ps;
4021 RECT rect;
4024 static void projected_textures_test(IDirect3DDevice9 *device,
4025 struct projected_textures_test_run tests[4])
4027 unsigned int i;
4029 static const DWORD vertex_shader[] =
4031 0xfffe0101, /* vs_1_1 */
4032 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4033 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4034 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4035 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4036 0x0000ffff /* end */
4038 static const DWORD pixel_shader[] =
4040 0xffff0103, /* ps_1_3 */
4041 0x00000042, 0xb00f0000, /* tex t0 */
4042 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4043 0x0000ffff /* end */
4045 IDirect3DVertexShader9 *vs = NULL;
4046 IDirect3DPixelShader9 *ps = NULL;
4047 IDirect3D9 *d3d;
4048 D3DCAPS9 caps;
4049 HRESULT hr;
4051 IDirect3DDevice9_GetDirect3D(device, &d3d);
4052 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4053 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4054 IDirect3D9_Release(d3d);
4056 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4058 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4059 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4061 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4063 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4064 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4068 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4070 hr = IDirect3DDevice9_BeginScene(device);
4071 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4072 if (FAILED(hr))
4073 return;
4075 for (i = 0; i < 4; ++i)
4077 DWORD value = 0xdeadbeef;
4078 static const float proj_quads[] =
4080 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4081 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4082 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4083 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4085 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4086 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4087 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4088 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4090 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4091 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4092 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4093 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4095 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4096 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4097 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4098 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4101 if (tests[i].vs)
4103 if (!vs)
4105 skip("Vertex shaders not supported, skipping\n");
4106 continue;
4108 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4110 else
4111 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4112 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4113 if (tests[i].ps)
4115 if (!ps)
4117 skip("Pixel shaders not supported, skipping\n");
4118 continue;
4120 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4122 else
4123 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4124 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4126 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4127 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4129 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4130 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4131 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4132 ok(SUCCEEDED(hr) && value == tests[i].flags,
4133 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4136 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4137 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4140 hr = IDirect3DDevice9_EndScene(device);
4141 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4143 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4144 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4145 if (vs) IDirect3DVertexShader9_Release(vs);
4146 if (ps) IDirect3DPixelShader9_Release(ps);
4148 for (i = 0; i < 4; ++i)
4150 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4151 check_rect(device, tests[i].rect, tests[i].message);
4154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4155 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4158 static void texture_transform_flags_test(void)
4160 HRESULT hr;
4161 IDirect3D9 *d3d;
4162 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4163 D3DCAPS9 caps;
4164 IDirect3DTexture9 *texture = NULL;
4165 IDirect3DVolumeTexture9 *volume = NULL;
4166 IDirect3DDevice9 *device;
4167 unsigned int x, y, z;
4168 D3DLOCKED_RECT lr;
4169 D3DLOCKED_BOX lb;
4170 D3DCOLOR color;
4171 ULONG refcount;
4172 HWND window;
4173 UINT w, h;
4174 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4175 float identity[16] = {1.0, 0.0, 0.0, 0.0,
4176 0.0, 1.0, 0.0, 0.0,
4177 0.0, 0.0, 1.0, 0.0,
4178 0.0, 0.0, 0.0, 1.0};
4179 static const D3DVERTEXELEMENT9 decl_elements[] = {
4180 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4181 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4182 D3DDECL_END()
4184 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4185 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4186 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4187 D3DDECL_END()
4189 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4190 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4191 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4192 D3DDECL_END()
4194 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4195 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4196 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4197 D3DDECL_END()
4199 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4200 0x00, 0xff, 0x00, 0x00,
4201 0x00, 0x00, 0x00, 0x00,
4202 0x00, 0x00, 0x00, 0x00};
4204 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4205 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4206 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4207 ok(!!d3d, "Failed to create a D3D object.\n");
4208 if (!(device = create_device(d3d, window, window, TRUE)))
4210 skip("Failed to create a D3D device, skipping tests.\n");
4211 goto done;
4214 memset(&lr, 0, sizeof(lr));
4215 memset(&lb, 0, sizeof(lb));
4216 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4217 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4218 fmt = D3DFMT_A16B16G16R16;
4220 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4221 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4222 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4223 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4224 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4225 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4226 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4227 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4228 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4229 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4231 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4232 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4233 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4234 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4235 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4236 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4237 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4238 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4239 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4241 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4242 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4243 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4244 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4245 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4247 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4249 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4251 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4252 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4253 w = min(1024, caps.MaxTextureWidth);
4254 h = min(1024, caps.MaxTextureHeight);
4255 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4256 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4257 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4258 if (!texture)
4260 skip("Failed to create the test texture.\n");
4261 IDirect3DDevice9_Release(device);
4262 goto done;
4265 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4266 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4267 * 1.0 in red and green for the x and y coords
4269 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4270 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4271 for(y = 0; y < h; y++) {
4272 for(x = 0; x < w; x++) {
4273 double r_f = (double) y / (double) h;
4274 double g_f = (double) x / (double) w;
4275 if(fmt == D3DFMT_A16B16G16R16) {
4276 unsigned short r, g;
4277 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4278 r = (unsigned short) (r_f * 65536.0);
4279 g = (unsigned short) (g_f * 65536.0);
4280 dst[0] = r;
4281 dst[1] = g;
4282 dst[2] = 0;
4283 dst[3] = 65535;
4284 } else {
4285 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4286 unsigned char r = (unsigned char) (r_f * 255.0);
4287 unsigned char g = (unsigned char) (g_f * 255.0);
4288 dst[0] = 0;
4289 dst[1] = g;
4290 dst[2] = r;
4291 dst[3] = 255;
4295 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4296 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4297 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4298 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4300 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4301 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4302 hr = IDirect3DDevice9_BeginScene(device);
4303 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4304 if(SUCCEEDED(hr))
4306 float quad1[] = {
4307 -1.0, -1.0, 0.1, 1.0, 1.0,
4308 -1.0, 0.0, 0.1, 1.0, 1.0,
4309 0.0, -1.0, 0.1, 1.0, 1.0,
4310 0.0, 0.0, 0.1, 1.0, 1.0,
4312 float quad2[] = {
4313 -1.0, 0.0, 0.1, 1.0, 1.0,
4314 -1.0, 1.0, 0.1, 1.0, 1.0,
4315 0.0, 0.0, 0.1, 1.0, 1.0,
4316 0.0, 1.0, 0.1, 1.0, 1.0,
4318 float quad3[] = {
4319 0.0, 0.0, 0.1, 0.5, 0.5,
4320 0.0, 1.0, 0.1, 0.5, 0.5,
4321 1.0, 0.0, 0.1, 0.5, 0.5,
4322 1.0, 1.0, 0.1, 0.5, 0.5,
4324 float quad4[] = {
4325 320, 480, 0.1, 1.0, 0.0, 1.0,
4326 320, 240, 0.1, 1.0, 0.0, 1.0,
4327 640, 480, 0.1, 1.0, 0.0, 1.0,
4328 640, 240, 0.1, 1.0, 0.0, 1.0,
4330 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4331 0.0, 0.0, 0.0, 0.0,
4332 0.0, 0.0, 0.0, 0.0,
4333 0.0, 0.0, 0.0, 0.0};
4335 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4336 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4337 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4339 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4341 /* What happens with transforms enabled? */
4342 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4343 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4345 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4347 /* What happens if 4 coords are used, but only 2 given ?*/
4348 mat[8] = 1.0;
4349 mat[13] = 1.0;
4350 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4351 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4352 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4353 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4355 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4357 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4358 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4359 * due to the coords in the vertices. (turns out red, indeed)
4361 memset(mat, 0, sizeof(mat));
4362 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4363 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4364 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4365 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4366 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4367 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4369 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4371 hr = IDirect3DDevice9_EndScene(device);
4372 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4374 color = getPixelColor(device, 160, 360);
4375 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4376 color = getPixelColor(device, 160, 120);
4377 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4378 color = getPixelColor(device, 480, 120);
4379 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4380 color = getPixelColor(device, 480, 360);
4381 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4382 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4383 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4388 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4390 hr = IDirect3DDevice9_BeginScene(device);
4391 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4392 if(SUCCEEDED(hr))
4394 float quad1[] = {
4395 -1.0, -1.0, 0.1, 0.8, 0.2,
4396 -1.0, 0.0, 0.1, 0.8, 0.2,
4397 0.0, -1.0, 0.1, 0.8, 0.2,
4398 0.0, 0.0, 0.1, 0.8, 0.2,
4400 float quad2[] = {
4401 -1.0, 0.0, 0.1, 0.5, 1.0,
4402 -1.0, 1.0, 0.1, 0.5, 1.0,
4403 0.0, 0.0, 0.1, 0.5, 1.0,
4404 0.0, 1.0, 0.1, 0.5, 1.0,
4406 float quad3[] = {
4407 0.0, 0.0, 0.1, 0.5, 1.0,
4408 0.0, 1.0, 0.1, 0.5, 1.0,
4409 1.0, 0.0, 0.1, 0.5, 1.0,
4410 1.0, 1.0, 0.1, 0.5, 1.0,
4412 float quad4[] = {
4413 0.0, -1.0, 0.1, 0.8, 0.2,
4414 0.0, 0.0, 0.1, 0.8, 0.2,
4415 1.0, -1.0, 0.1, 0.8, 0.2,
4416 1.0, 0.0, 0.1, 0.8, 0.2,
4418 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4419 0.0, 0.0, 0.0, 0.0,
4420 0.0, 1.0, 0.0, 0.0,
4421 0.0, 0.0, 0.0, 0.0};
4423 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4424 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4425 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4426 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4427 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4430 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4432 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4433 * it behaves like COUNT2 because normal textures require 2 coords. */
4434 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4435 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4436 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4437 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4439 /* Just to be sure, the same as quad2 above */
4440 memset(mat, 0, sizeof(mat));
4441 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4442 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4443 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4444 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4446 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4448 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4449 * used? And what happens to the first? */
4450 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4451 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4453 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4455 hr = IDirect3DDevice9_EndScene(device);
4456 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4458 color = getPixelColor(device, 160, 360);
4459 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4460 color = getPixelColor(device, 160, 120);
4461 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4462 color = getPixelColor(device, 480, 120);
4463 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4464 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4465 color = getPixelColor(device, 480, 360);
4466 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4467 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4469 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4471 IDirect3DTexture9_Release(texture);
4473 /* Test projected textures, without any fancy matrices */
4474 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4475 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4476 if (SUCCEEDED(hr))
4478 struct projected_textures_test_run projected_tests_1[4] =
4481 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4482 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4483 decl3,
4484 FALSE, TRUE,
4485 {120, 300, 240, 390},
4488 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4489 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4490 decl3,
4491 FALSE, TRUE,
4492 {400, 360, 480, 420},
4494 /* Try with some invalid values */
4496 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4497 0xffffffff,
4498 decl3,
4499 FALSE, TRUE,
4500 {120, 60, 240, 150}
4503 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4504 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4505 decl4,
4506 FALSE, TRUE,
4507 {340, 210, 360, 225},
4510 struct projected_textures_test_run projected_tests_2[4] =
4513 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4514 D3DTTFF_PROJECTED,
4515 decl3,
4516 FALSE, TRUE,
4517 {120, 300, 240, 390},
4520 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4521 D3DTTFF_PROJECTED,
4522 decl,
4523 FALSE, TRUE,
4524 {400, 360, 480, 420},
4527 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4528 0xffffffff,
4529 decl,
4530 FALSE, TRUE,
4531 {80, 120, 160, 180},
4534 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4535 D3DTTFF_COUNT1,
4536 decl4,
4537 FALSE, TRUE,
4538 {340, 210, 360, 225},
4541 struct projected_textures_test_run projected_tests_3[4] =
4544 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4545 D3DTTFF_PROJECTED,
4546 decl3,
4547 TRUE, FALSE,
4548 {120, 300, 240, 390},
4551 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4552 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4553 decl3,
4554 TRUE, TRUE,
4555 {440, 300, 560, 390},
4558 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4559 0xffffffff,
4560 decl3,
4561 TRUE, TRUE,
4562 {120, 60, 240, 150},
4565 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4566 D3DTTFF_PROJECTED,
4567 decl3,
4568 FALSE, FALSE,
4569 {440, 60, 560, 150},
4573 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4574 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4576 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4577 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4578 for(x = 0; x < 4; x++) {
4579 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4581 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4582 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4583 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4586 projected_textures_test(device, projected_tests_1);
4587 projected_textures_test(device, projected_tests_2);
4588 projected_textures_test(device, projected_tests_3);
4590 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4591 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4592 IDirect3DTexture9_Release(texture);
4595 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4596 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4597 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4598 * Thus watch out if sampling from texels between 0 and 1.
4600 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4601 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4602 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4603 if(!volume) {
4604 skip("Failed to create a volume texture\n");
4605 goto out;
4608 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4609 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4610 for(z = 0; z < 32; z++) {
4611 for(y = 0; y < 32; y++) {
4612 for(x = 0; x < 32; x++) {
4613 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4614 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4615 float r_f = (float) x / 31.0;
4616 float g_f = (float) y / 31.0;
4617 float b_f = (float) z / 31.0;
4619 if(fmt == D3DFMT_A16B16G16R16) {
4620 unsigned short *mem_s = mem;
4621 mem_s[0] = r_f * 65535.0;
4622 mem_s[1] = g_f * 65535.0;
4623 mem_s[2] = b_f * 65535.0;
4624 mem_s[3] = 65535;
4625 } else {
4626 unsigned char *mem_c = mem;
4627 mem_c[0] = b_f * 255.0;
4628 mem_c[1] = g_f * 255.0;
4629 mem_c[2] = r_f * 255.0;
4630 mem_c[3] = 255;
4635 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4636 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4638 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4639 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4641 hr = IDirect3DDevice9_BeginScene(device);
4642 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4643 if(SUCCEEDED(hr))
4645 float quad1[] = {
4646 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4647 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4648 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4649 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4651 float quad2[] = {
4652 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4653 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4654 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4655 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4657 float quad3[] = {
4658 0.0, 0.0, 0.1, 0.0, 0.0,
4659 0.0, 1.0, 0.1, 0.0, 0.0,
4660 1.0, 0.0, 0.1, 0.0, 0.0,
4661 1.0, 1.0, 0.1, 0.0, 0.0
4663 float quad4[] = {
4664 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4665 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4666 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4667 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4669 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4670 0.0, 0.0, 1.0, 0.0,
4671 0.0, 1.0, 0.0, 0.0,
4672 0.0, 0.0, 0.0, 1.0};
4673 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4676 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4677 * values
4679 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4680 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4681 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4682 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4684 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4686 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4687 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4688 * otherwise the w will be missing(blue).
4689 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4690 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4691 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4692 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4693 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4694 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4696 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4697 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4699 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4700 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4702 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4704 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4706 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4707 * disable. ATI extends it up to the amount of values needed for the volume texture
4709 memset(mat, 0, sizeof(mat));
4710 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4711 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4712 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4713 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4714 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4715 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4717 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4719 hr = IDirect3DDevice9_EndScene(device);
4720 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4723 color = getPixelColor(device, 160, 360);
4724 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4725 color = getPixelColor(device, 160, 120);
4726 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4727 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4728 color = getPixelColor(device, 480, 120);
4729 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4730 color = getPixelColor(device, 480, 360);
4731 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4733 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4734 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4736 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4737 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4738 hr = IDirect3DDevice9_BeginScene(device);
4739 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4740 if(SUCCEEDED(hr))
4742 float quad1[] = {
4743 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4744 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4745 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4746 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4748 float quad2[] = {
4749 -1.0, 0.0, 0.1,
4750 -1.0, 1.0, 0.1,
4751 0.0, 0.0, 0.1,
4752 0.0, 1.0, 0.1,
4754 float quad3[] = {
4755 0.0, 0.0, 0.1, 1.0,
4756 0.0, 1.0, 0.1, 1.0,
4757 1.0, 0.0, 0.1, 1.0,
4758 1.0, 1.0, 0.1, 1.0
4760 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4761 0.0, 0.0, 0.0, 0.0,
4762 0.0, 0.0, 0.0, 0.0,
4763 0.0, 1.0, 0.0, 0.0};
4764 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4765 1.0, 0.0, 0.0, 0.0,
4766 0.0, 1.0, 0.0, 0.0,
4767 0.0, 0.0, 1.0, 0.0};
4768 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4771 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4772 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4773 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4774 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4775 * 4th *input* coordinate.
4777 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4779 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4780 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4781 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4782 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4784 /* None passed */
4785 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4786 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4787 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792 /* 4 used, 1 passed */
4793 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4794 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4795 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4798 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4800 hr = IDirect3DDevice9_EndScene(device);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4803 color = getPixelColor(device, 160, 360);
4804 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4805 color = getPixelColor(device, 160, 120);
4806 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4807 color = getPixelColor(device, 480, 120);
4808 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4809 /* Quad4: unused */
4811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4812 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4814 IDirect3DVolumeTexture9_Release(volume);
4816 out:
4817 IDirect3DVertexDeclaration9_Release(decl);
4818 IDirect3DVertexDeclaration9_Release(decl2);
4819 IDirect3DVertexDeclaration9_Release(decl3);
4820 IDirect3DVertexDeclaration9_Release(decl4);
4821 refcount = IDirect3DDevice9_Release(device);
4822 ok(!refcount, "Device has %u references left.\n", refcount);
4823 done:
4824 IDirect3D9_Release(d3d);
4825 DestroyWindow(window);
4828 static void texdepth_test(void)
4830 IDirect3DPixelShader9 *shader;
4831 IDirect3DDevice9 *device;
4832 IDirect3D9 *d3d;
4833 ULONG refcount;
4834 D3DCAPS9 caps;
4835 DWORD color;
4836 HWND window;
4837 HRESULT hr;
4839 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
4840 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
4841 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
4842 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
4843 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
4844 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
4845 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
4846 static const DWORD shader_code[] =
4848 0xffff0104, /* ps_1_4 */
4849 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4850 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4851 0x0000fffd, /* phase */
4852 0x00000057, 0x800f0005, /* texdepth r5 */
4853 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4854 0x0000ffff /* end */
4856 static const float vertex[] =
4858 -1.0f, -1.0f, 0.0f,
4859 -1.0f, 1.0f, 0.0f,
4860 1.0f, -1.0f, 1.0f,
4861 1.0f, 1.0f, 1.0f,
4864 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4865 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4866 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4867 ok(!!d3d, "Failed to create a D3D object.\n");
4868 if (!(device = create_device(d3d, window, window, TRUE)))
4870 skip("Failed to create a D3D device, skipping tests.\n");
4871 goto done;
4874 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4875 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4876 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4878 skip("No ps_1_1 support, skipping tests.\n");
4879 IDirect3DDevice9_Release(device);
4880 goto done;
4883 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4884 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4887 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4889 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4891 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4895 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4896 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4897 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4899 /* Fill the depth buffer with a gradient */
4900 hr = IDirect3DDevice9_BeginScene(device);
4901 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4902 if(SUCCEEDED(hr))
4904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4905 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4906 hr = IDirect3DDevice9_EndScene(device);
4907 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4910 /* Now perform the actual tests. Same geometry, but with the shader */
4911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4912 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4915 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4916 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4918 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4919 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4920 hr = IDirect3DDevice9_BeginScene(device);
4921 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4922 if(SUCCEEDED(hr))
4924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4925 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4927 hr = IDirect3DDevice9_EndScene(device);
4928 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4931 color = getPixelColor(device, 158, 240);
4932 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4933 color = getPixelColor(device, 162, 240);
4934 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\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_data2, 1);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4944 hr = IDirect3DDevice9_BeginScene(device);
4945 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4946 if(SUCCEEDED(hr))
4948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4949 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4951 hr = IDirect3DDevice9_EndScene(device);
4952 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4955 color = getPixelColor(device, 318, 240);
4956 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4957 color = getPixelColor(device, 322, 240);
4958 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4960 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4961 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4963 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4964 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4966 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4967 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4968 hr = IDirect3DDevice9_BeginScene(device);
4969 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4970 if(SUCCEEDED(hr))
4972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4973 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4975 hr = IDirect3DDevice9_EndScene(device);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4979 color = getPixelColor(device, 1, 240);
4980 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4982 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4983 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4985 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4986 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4988 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4989 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4990 hr = IDirect3DDevice9_BeginScene(device);
4991 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4992 if(SUCCEEDED(hr))
4994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4995 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4997 hr = IDirect3DDevice9_EndScene(device);
4998 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5000 color = getPixelColor(device, 318, 240);
5001 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5002 color = getPixelColor(device, 322, 240);
5003 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5006 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5009 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5011 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5012 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5013 hr = IDirect3DDevice9_BeginScene(device);
5014 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5015 if(SUCCEEDED(hr))
5017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5018 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5020 hr = IDirect3DDevice9_EndScene(device);
5021 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5024 color = getPixelColor(device, 1, 240);
5025 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5027 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5028 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5031 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5033 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5034 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5035 hr = IDirect3DDevice9_BeginScene(device);
5036 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5037 if(SUCCEEDED(hr))
5039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5040 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5042 hr = IDirect3DDevice9_EndScene(device);
5043 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5046 color = getPixelColor(device, 638, 240);
5047 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5049 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5050 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5052 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5053 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5055 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5056 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5057 hr = IDirect3DDevice9_BeginScene(device);
5058 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5059 if(SUCCEEDED(hr))
5061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5062 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5064 hr = IDirect3DDevice9_EndScene(device);
5065 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5068 color = getPixelColor(device, 638, 240);
5069 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5072 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5074 IDirect3DPixelShader9_Release(shader);
5075 refcount = IDirect3DDevice9_Release(device);
5076 ok(!refcount, "Device has %u references left.\n", refcount);
5077 done:
5078 IDirect3D9_Release(d3d);
5079 DestroyWindow(window);
5082 static void texkill_test(void)
5084 IDirect3DPixelShader9 *shader;
5085 IDirect3DDevice9 *device;
5086 IDirect3D9 *d3d;
5087 ULONG refcount;
5088 D3DCAPS9 caps;
5089 DWORD color;
5090 HWND window;
5091 HRESULT hr;
5093 static const float vertex[] =
5095 /* bottom top right left */
5096 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5097 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5098 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5099 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5101 static const DWORD shader_code_11[] =
5103 0xffff0101, /* ps_1_1 */
5104 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5105 0x00000041, 0xb00f0000, /* texkill t0 */
5106 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5107 0x0000ffff /* end */
5109 static const DWORD shader_code_20[] =
5111 0xffff0200, /* ps_2_0 */
5112 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5113 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5114 0x01000041, 0xb00f0000, /* texkill t0 */
5115 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5116 0x0000ffff /* end */
5119 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5120 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5121 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5122 ok(!!d3d, "Failed to create a D3D object.\n");
5123 if (!(device = create_device(d3d, window, window, TRUE)))
5125 skip("Failed to create a D3D device, skipping tests.\n");
5126 goto done;
5129 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5130 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5131 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5133 skip("No ps_1_1 support, skipping tests.\n");
5134 IDirect3DDevice9_Release(device);
5135 goto done;
5138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5139 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5140 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5141 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5143 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5144 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5145 hr = IDirect3DDevice9_BeginScene(device);
5146 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5147 if(SUCCEEDED(hr))
5149 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5150 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5152 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5153 hr = IDirect3DDevice9_EndScene(device);
5154 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5156 color = getPixelColor(device, 63, 46);
5157 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5158 color = getPixelColor(device, 66, 46);
5159 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5160 color = getPixelColor(device, 63, 49);
5161 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5162 color = getPixelColor(device, 66, 49);
5163 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5165 color = getPixelColor(device, 578, 46);
5166 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5167 color = getPixelColor(device, 575, 46);
5168 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5169 color = getPixelColor(device, 578, 49);
5170 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5171 color = getPixelColor(device, 575, 49);
5172 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5174 color = getPixelColor(device, 63, 430);
5175 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5176 color = getPixelColor(device, 63, 433);
5177 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5178 color = getPixelColor(device, 66, 433);
5179 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5180 color = getPixelColor(device, 66, 430);
5181 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5183 color = getPixelColor(device, 578, 430);
5184 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5185 color = getPixelColor(device, 578, 433);
5186 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5187 color = getPixelColor(device, 575, 433);
5188 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5189 color = getPixelColor(device, 575, 430);
5190 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5192 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5195 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5196 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5197 IDirect3DPixelShader9_Release(shader);
5199 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5200 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5201 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5203 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5204 IDirect3DDevice9_Release(device);
5205 goto done;
5208 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5209 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5210 hr = IDirect3DDevice9_BeginScene(device);
5211 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5212 if(SUCCEEDED(hr))
5214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5215 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5216 hr = IDirect3DDevice9_EndScene(device);
5217 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5220 color = getPixelColor(device, 63, 46);
5221 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5222 color = getPixelColor(device, 66, 46);
5223 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5224 color = getPixelColor(device, 63, 49);
5225 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5226 color = getPixelColor(device, 66, 49);
5227 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5229 color = getPixelColor(device, 578, 46);
5230 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5231 color = getPixelColor(device, 575, 46);
5232 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5233 color = getPixelColor(device, 578, 49);
5234 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5235 color = getPixelColor(device, 575, 49);
5236 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5238 color = getPixelColor(device, 63, 430);
5239 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5240 color = getPixelColor(device, 63, 433);
5241 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5242 color = getPixelColor(device, 66, 433);
5243 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5244 color = getPixelColor(device, 66, 430);
5245 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5247 color = getPixelColor(device, 578, 430);
5248 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5249 color = getPixelColor(device, 578, 433);
5250 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5251 color = getPixelColor(device, 575, 433);
5252 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5253 color = getPixelColor(device, 575, 430);
5254 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5257 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5259 IDirect3DPixelShader9_Release(shader);
5260 refcount = IDirect3DDevice9_Release(device);
5261 ok(!refcount, "Device has %u references left.\n", refcount);
5262 done:
5263 IDirect3D9_Release(d3d);
5264 DestroyWindow(window);
5267 static void x8l8v8u8_test(void)
5269 IDirect3DPixelShader9 *shader2;
5270 IDirect3DPixelShader9 *shader;
5271 IDirect3DTexture9 *texture;
5272 IDirect3DDevice9 *device;
5273 D3DLOCKED_RECT lr;
5274 IDirect3D9 *d3d;
5275 ULONG refcount;
5276 D3DCAPS9 caps;
5277 DWORD color;
5278 HWND window;
5279 HRESULT hr;
5281 static const DWORD shader_code[] =
5283 0xffff0101, /* ps_1_1 */
5284 0x00000042, 0xb00f0000, /* tex t0 */
5285 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5286 0x0000ffff /* end */
5288 static const DWORD shader_code2[] =
5290 0xffff0101, /* ps_1_1 */
5291 0x00000042, 0xb00f0000, /* tex t0 */
5292 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
5293 0x0000ffff /* end */
5295 static const float quad[] =
5297 -1.0f, -1.0f, 0.1f, 0.5f, 0.5f,
5298 -1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5299 1.0f, -1.0f, 0.1f, 0.5f, 0.5f,
5300 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5303 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5304 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5305 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5306 ok(!!d3d, "Failed to create a D3D object.\n");
5307 if (!(device = create_device(d3d, window, window, TRUE)))
5309 skip("Failed to create a D3D device, skipping tests.\n");
5310 goto done;
5313 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5314 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5315 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5317 skip("No ps_1_1 support, skipping tests.\n");
5318 IDirect3DDevice9_Release(device);
5319 goto done;
5321 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5322 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8)))
5324 skip("No D3DFMT_X8L8V8U8 support, skipping tests.\n");
5325 IDirect3DDevice9_Release(device);
5326 goto done;
5329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5332 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5333 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5334 memset(&lr, 0, sizeof(lr));
5335 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5336 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5337 *((DWORD *) lr.pBits) = 0x11ca3141;
5338 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5339 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5341 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5343 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5344 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5346 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5347 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5348 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5349 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5350 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5351 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5353 hr = IDirect3DDevice9_BeginScene(device);
5354 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5355 if(SUCCEEDED(hr))
5357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5358 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5360 hr = IDirect3DDevice9_EndScene(device);
5361 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5363 color = getPixelColor(device, 578, 430);
5364 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5365 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5366 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5369 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5370 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5371 hr = IDirect3DDevice9_BeginScene(device);
5372 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5373 if(SUCCEEDED(hr))
5375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5376 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5378 hr = IDirect3DDevice9_EndScene(device);
5379 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5381 color = getPixelColor(device, 578, 430);
5382 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5383 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5384 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5386 IDirect3DPixelShader9_Release(shader);
5387 IDirect3DPixelShader9_Release(shader2);
5388 IDirect3DTexture9_Release(texture);
5389 refcount = IDirect3DDevice9_Release(device);
5390 ok(!refcount, "Device has %u references left.\n", refcount);
5391 done:
5392 IDirect3D9_Release(d3d);
5393 DestroyWindow(window);
5396 static void autogen_mipmap_test(void)
5398 IDirect3DTexture9 *texture = NULL;
5399 IDirect3DSurface9 *surface;
5400 IDirect3DDevice9 *device;
5401 unsigned int x, y;
5402 D3DLOCKED_RECT lr;
5403 IDirect3D9 *d3d;
5404 D3DCOLOR color;
5405 ULONG refcount;
5406 HWND window;
5407 HRESULT hr;
5409 static const RECT r1 = {256, 256, 512, 512};
5410 static const RECT r2 = {512, 256, 768, 512};
5411 static const RECT r3 = {256, 512, 512, 768};
5412 static const RECT r4 = {512, 512, 768, 768};
5413 static const float quad[] =
5415 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5416 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5417 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5418 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5421 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5422 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5423 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5424 ok(!!d3d, "Failed to create a D3D object.\n");
5425 if (!(device = create_device(d3d, window, window, TRUE)))
5427 skip("Failed to create a D3D device, skipping tests.\n");
5428 goto done;
5431 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5432 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5434 skip("No autogenmipmap support.\n");
5435 IDirect3DDevice9_Release(device);
5436 goto done;
5439 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5440 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5442 /* Make the mipmap big, so that a smaller mipmap is used
5444 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5445 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5446 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5448 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5449 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5450 memset(&lr, 0, sizeof(lr));
5451 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5452 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5453 for(y = 0; y < 1024; y++) {
5454 for(x = 0; x < 1024; x++) {
5455 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5456 POINT pt;
5458 pt.x = x;
5459 pt.y = y;
5460 if(PtInRect(&r1, pt)) {
5461 *dst = 0xffff0000;
5462 } else if(PtInRect(&r2, pt)) {
5463 *dst = 0xff00ff00;
5464 } else if(PtInRect(&r3, pt)) {
5465 *dst = 0xff0000ff;
5466 } else if(PtInRect(&r4, pt)) {
5467 *dst = 0xff000000;
5468 } else {
5469 *dst = 0xffffffff;
5473 hr = IDirect3DSurface9_UnlockRect(surface);
5474 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5475 IDirect3DSurface9_Release(surface);
5477 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5478 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5479 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5480 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5481 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5482 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5484 hr = IDirect3DDevice9_BeginScene(device);
5485 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5486 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5487 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5489 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5490 hr = IDirect3DDevice9_EndScene(device);
5491 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5492 IDirect3DTexture9_Release(texture);
5494 color = getPixelColor(device, 200, 200);
5495 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5496 color = getPixelColor(device, 280, 200);
5497 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5498 color = getPixelColor(device, 360, 200);
5499 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5500 color = getPixelColor(device, 440, 200);
5501 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5502 color = getPixelColor(device, 200, 270);
5503 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5504 color = getPixelColor(device, 280, 270);
5505 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5506 color = getPixelColor(device, 360, 270);
5507 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5508 color = getPixelColor(device, 440, 270);
5509 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5510 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5511 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5513 refcount = IDirect3DDevice9_Release(device);
5514 ok(!refcount, "Device has %u references left.\n", refcount);
5515 done:
5516 IDirect3D9_Release(d3d);
5517 DestroyWindow(window);
5520 static void test_constant_clamp_vs(void)
5522 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5523 IDirect3DVertexDeclaration9 *decl;
5524 IDirect3DDevice9 *device;
5525 IDirect3D9 *d3d;
5526 D3DCOLOR color;
5527 ULONG refcount;
5528 D3DCAPS9 caps;
5529 HWND window;
5530 HRESULT hr;
5532 static const DWORD shader_code_11[] =
5534 0xfffe0101, /* vs_1_1 */
5535 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5536 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5537 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5538 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5539 0x0000ffff /* end */
5541 static const DWORD shader_code_11_2[] =
5543 0xfffe0101, /* vs_1_1 */
5544 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5545 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5546 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5547 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5548 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5549 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5550 0x0000ffff /* end */
5552 static const DWORD shader_code_20[] =
5554 0xfffe0200, /* vs_2_0 */
5555 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5556 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5557 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5558 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5559 0x0000ffff /* end */
5561 static const DWORD shader_code_20_2[] =
5563 0xfffe0200, /* vs_2_0 */
5564 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5565 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5566 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5567 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5568 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5569 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5570 0x0000ffff /* end */
5572 static const D3DVERTEXELEMENT9 decl_elements[] =
5574 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5575 D3DDECL_END()
5577 static const float quad1[] =
5579 -1.0f, -1.0f, 0.1f,
5580 -1.0f, 0.0f, 0.1f,
5581 0.0f, -1.0f, 0.1f,
5582 0.0f, 0.0f, 0.1f,
5584 static const float quad2[] =
5586 0.0f, -1.0f, 0.1f,
5587 0.0f, 0.0f, 0.1f,
5588 1.0f, -1.0f, 0.1f,
5589 1.0f, 0.0f, 0.1f,
5591 static const float quad3[] =
5593 0.0f, 0.0f, 0.1f,
5594 0.0f, 1.0f, 0.1f,
5595 1.0f, 0.0f, 0.1f,
5596 1.0f, 1.0f, 0.1f,
5598 static const float quad4[] =
5600 -1.0f, 0.0f, 0.1f,
5601 -1.0f, 1.0f, 0.1f,
5602 0.0f, 0.0f, 0.1f,
5603 0.0f, 1.0f, 0.1f,
5605 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5606 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5608 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5609 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5610 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5611 ok(!!d3d, "Failed to create a D3D object.\n");
5612 if (!(device = create_device(d3d, window, window, TRUE)))
5614 skip("Failed to create a D3D device, skipping tests.\n");
5615 goto done;
5618 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5619 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5620 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
5622 skip("No vs_1_1 support, skipping tests.\n");
5623 IDirect3DDevice9_Release(device);
5624 goto done;
5627 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5628 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5630 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5631 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5632 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5634 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5635 if(FAILED(hr)) shader_20 = NULL;
5636 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5637 if(FAILED(hr)) shader_20_2 = NULL;
5638 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5639 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5641 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5642 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5643 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5644 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5645 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5646 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5648 hr = IDirect3DDevice9_BeginScene(device);
5649 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5650 if(SUCCEEDED(hr))
5652 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5653 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5655 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5657 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5658 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5660 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5662 if(shader_20) {
5663 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5664 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5666 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5669 if(shader_20_2) {
5670 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5671 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5673 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5676 hr = IDirect3DDevice9_EndScene(device);
5677 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5680 color = getPixelColor(device, 160, 360);
5681 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5682 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5683 color = getPixelColor(device, 480, 360);
5684 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5685 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5686 if(shader_20) {
5687 color = getPixelColor(device, 480, 120);
5688 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5689 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5691 if(shader_20_2) {
5692 color = getPixelColor(device, 160, 120);
5693 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5694 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5696 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5697 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5699 IDirect3DVertexDeclaration9_Release(decl);
5700 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5701 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5702 IDirect3DVertexShader9_Release(shader_11_2);
5703 IDirect3DVertexShader9_Release(shader_11);
5704 refcount = IDirect3DDevice9_Release(device);
5705 ok(!refcount, "Device has %u references left.\n", refcount);
5706 done:
5707 IDirect3D9_Release(d3d);
5708 DestroyWindow(window);
5711 static void constant_clamp_ps_test(void)
5713 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5714 IDirect3DDevice9 *device;
5715 IDirect3D9 *d3d;
5716 ULONG refcount;
5717 D3DCAPS9 caps;
5718 DWORD color;
5719 HWND window;
5720 HRESULT hr;
5722 static const DWORD shader_code_11[] =
5724 0xffff0101, /* ps_1_1 */
5725 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5726 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5727 0x0000ffff /* end */
5729 static const DWORD shader_code_12[] =
5731 0xffff0102, /* ps_1_2 */
5732 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5733 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5734 0x0000ffff /* end */
5736 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
5737 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
5738 * unlikely that 1.3 shaders are different. During development of this
5739 * test, 1.3 shaders were verified too. */
5740 static const DWORD shader_code_14[] =
5742 0xffff0104, /* ps_1_4 */
5743 /* Try to make one constant local. It gets clamped too, although the
5744 * binary contains the bigger numbers. */
5745 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5746 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5747 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5748 0x0000ffff /* end */
5750 static const DWORD shader_code_20[] =
5752 0xffff0200, /* ps_2_0 */
5753 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5754 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5755 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5756 0x0000ffff /* end */
5758 static const float quad1[] =
5760 -1.0f, -1.0f, 0.1f,
5761 -1.0f, 0.0f, 0.1f,
5762 0.0f, -1.0f, 0.1f,
5763 0.0f, 0.0f, 0.1f,
5765 static const float quad2[] =
5767 0.0f, -1.0f, 0.1f,
5768 0.0f, 0.0f, 0.1f,
5769 1.0f, -1.0f, 0.1f,
5770 1.0f, 0.0f, 0.1f,
5772 static const float quad3[] =
5774 0.0f, 0.0f, 0.1f,
5775 0.0f, 1.0f, 0.1f,
5776 1.0f, 0.0f, 0.1f,
5777 1.0f, 1.0f, 0.1f,
5779 static const float quad4[] =
5781 -1.0f, 0.0f, 0.1f,
5782 -1.0f, 1.0f, 0.1f,
5783 0.0f, 0.0f, 0.1f,
5784 0.0f, 1.0f, 0.1f,
5786 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5787 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5789 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5790 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5792 ok(!!d3d, "Failed to create a D3D object.\n");
5793 if (!(device = create_device(d3d, window, window, TRUE)))
5795 skip("Failed to create a D3D device, skipping tests.\n");
5796 goto done;
5799 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5800 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5801 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5803 skip("No ps_1_4 support, skipping tests.\n");
5804 IDirect3DDevice9_Release(device);
5805 goto done;
5808 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5809 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5811 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5813 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5814 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5815 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5816 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5817 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5818 if(FAILED(hr)) shader_20 = NULL;
5820 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5821 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5822 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5823 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5824 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5825 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5827 hr = IDirect3DDevice9_BeginScene(device);
5828 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5829 if(SUCCEEDED(hr))
5831 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5832 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5834 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5836 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5837 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5839 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5841 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5842 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5843 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5844 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5846 if(shader_20) {
5847 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5848 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5849 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5850 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5853 hr = IDirect3DDevice9_EndScene(device);
5854 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5857 color = getPixelColor(device, 160, 360);
5858 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5859 "quad 1 has color %08x, expected 0x00808000\n", color);
5860 color = getPixelColor(device, 480, 360);
5861 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5862 "quad 2 has color %08x, expected 0x00808000\n", color);
5863 color = getPixelColor(device, 480, 120);
5864 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5865 "quad 3 has color %08x, expected 0x00808000\n", color);
5866 if(shader_20) {
5867 color = getPixelColor(device, 160, 120);
5868 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5869 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5872 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5874 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5875 IDirect3DPixelShader9_Release(shader_14);
5876 IDirect3DPixelShader9_Release(shader_12);
5877 IDirect3DPixelShader9_Release(shader_11);
5878 refcount = IDirect3DDevice9_Release(device);
5879 ok(!refcount, "Device has %u references left.\n", refcount);
5880 done:
5881 IDirect3D9_Release(d3d);
5882 DestroyWindow(window);
5885 static void dp2add_ps_test(void)
5887 IDirect3DPixelShader9 *shader_dp2add_sat;
5888 IDirect3DPixelShader9 *shader_dp2add;
5889 IDirect3DDevice9 *device;
5890 IDirect3D9 *d3d;
5891 ULONG refcount;
5892 D3DCAPS9 caps;
5893 DWORD color;
5894 HWND window;
5895 HRESULT hr;
5897 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5898 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5899 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5900 * r0 first.
5901 * The result here for the r,g,b components should be roughly 0.5:
5902 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5903 static const DWORD shader_code_dp2add[] = {
5904 0xffff0200, /* ps_2_0 */
5905 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5907 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5908 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5910 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5911 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5912 0x0000ffff /* end */
5915 /* Test the _sat modifier, too. Result here should be:
5916 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5917 * _SAT: ==> 1.0
5918 * ADD: (1.0 + -0.5) = 0.5
5920 static const DWORD shader_code_dp2add_sat[] = {
5921 0xffff0200, /* ps_2_0 */
5922 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5924 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5925 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5926 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5928 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5929 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5930 0x0000ffff /* end */
5932 static const float quad[] =
5934 -1.0f, -1.0f, 0.1f,
5935 -1.0f, 1.0f, 0.1f,
5936 1.0f, -1.0f, 0.1f,
5937 1.0f, 1.0f, 0.1f,
5940 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5941 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5942 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5943 ok(!!d3d, "Failed to create a D3D object.\n");
5944 if (!(device = create_device(d3d, window, window, TRUE)))
5946 skip("Failed to create a D3D device, skipping tests.\n");
5947 goto done;
5950 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5951 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5952 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
5954 skip("No ps_2_0 support, skipping tests.\n");
5955 IDirect3DDevice9_Release(device);
5956 goto done;
5959 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
5960 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5962 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5963 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5965 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5966 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5968 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5969 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5971 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5972 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5973 hr = IDirect3DDevice9_BeginScene(device);
5974 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5976 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
5977 hr = IDirect3DDevice9_EndScene(device);
5978 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5980 color = getPixelColor(device, 360, 240);
5981 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
5983 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5984 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
5985 IDirect3DPixelShader9_Release(shader_dp2add);
5987 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5988 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5989 hr = IDirect3DDevice9_BeginScene(device);
5990 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5992 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
5993 hr = IDirect3DDevice9_EndScene(device);
5994 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5996 color = getPixelColor(device, 360, 240);
5997 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
5999 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6000 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6001 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6003 refcount = IDirect3DDevice9_Release(device);
6004 ok(!refcount, "Device has %u references left.\n", refcount);
6005 done:
6006 IDirect3D9_Release(d3d);
6007 DestroyWindow(window);
6010 static void cnd_test(void)
6012 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6013 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6014 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6015 IDirect3DDevice9 *device;
6016 IDirect3D9 *d3d;
6017 ULONG refcount;
6018 D3DCAPS9 caps;
6019 HWND window;
6020 DWORD color;
6021 HRESULT hr;
6023 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6024 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6025 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6026 * in 1.x pixel shaders. */
6027 static const DWORD shader_code_11[] =
6029 0xffff0101, /* ps_1_1 */
6030 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6031 0x00000040, 0xb00f0000, /* texcoord t0 */
6032 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6033 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6034 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6035 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6036 0x0000ffff /* end */
6038 static const DWORD shader_code_12[] =
6040 0xffff0102, /* ps_1_2 */
6041 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6042 0x00000040, 0xb00f0000, /* texcoord t0 */
6043 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6044 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6045 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6046 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6047 0x0000ffff /* end */
6049 static const DWORD shader_code_13[] =
6051 0xffff0103, /* ps_1_3 */
6052 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6053 0x00000040, 0xb00f0000, /* texcoord t0 */
6054 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6055 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6056 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6057 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6058 0x0000ffff /* end */
6060 static const DWORD shader_code_14[] =
6062 0xffff0104, /* ps_1_3 */
6063 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6064 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6065 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6066 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6067 0x0000ffff /* end */
6070 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6071 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6072 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6073 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6074 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6075 * well enough.
6077 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6078 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6079 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6080 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6082 static const DWORD shader_code_11_coissue[] =
6084 0xffff0101, /* ps_1_1 */
6085 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6086 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6087 0x00000040, 0xb00f0000, /* texcoord t0 */
6088 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6089 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6090 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6091 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6092 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6093 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6094 0x0000ffff /* end */
6096 static const DWORD shader_code_11_coissue_2[] =
6098 0xffff0101, /* ps_1_1 */
6099 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6100 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6101 0x00000040, 0xb00f0000, /* texcoord t0 */
6102 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6103 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6104 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6105 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6106 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6107 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6108 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6109 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6110 0x0000ffff /* end */
6112 static const DWORD shader_code_12_coissue[] =
6114 0xffff0102, /* ps_1_2 */
6115 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6116 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6117 0x00000040, 0xb00f0000, /* texcoord t0 */
6118 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6119 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6120 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6121 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6122 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6123 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6124 0x0000ffff /* end */
6126 static const DWORD shader_code_12_coissue_2[] =
6128 0xffff0102, /* ps_1_2 */
6129 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6130 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6131 0x00000040, 0xb00f0000, /* texcoord t0 */
6132 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6133 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6134 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6135 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6136 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6137 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6138 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6139 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6140 0x0000ffff /* end */
6142 static const DWORD shader_code_13_coissue[] =
6144 0xffff0103, /* ps_1_3 */
6145 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6146 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6147 0x00000040, 0xb00f0000, /* texcoord t0 */
6148 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6149 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6150 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6151 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6152 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6153 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6154 0x0000ffff /* end */
6156 static const DWORD shader_code_13_coissue_2[] =
6158 0xffff0103, /* ps_1_3 */
6159 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6160 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6161 0x00000040, 0xb00f0000, /* texcoord t0 */
6162 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6163 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6164 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6165 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6166 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6167 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6168 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6169 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6170 0x0000ffff /* end */
6172 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6173 * texcrd result to cnd, it will compare against 0.5. */
6174 static const DWORD shader_code_14_coissue[] =
6176 0xffff0104, /* ps_1_4 */
6177 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6178 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6179 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6180 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6181 0x0000ffff /* end */
6183 static const DWORD shader_code_14_coissue_2[] =
6185 0xffff0104, /* ps_1_4 */
6186 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6187 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6188 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6189 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6190 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6191 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6192 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6193 0x0000ffff /* end */
6195 static const float quad1[] =
6197 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6198 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6199 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6200 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6202 static const float quad2[] =
6204 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6205 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6206 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6207 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6209 static const float quad3[] =
6211 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6212 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6213 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6214 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6216 static const float quad4[] =
6218 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6219 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6220 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6221 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6223 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6224 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6225 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6226 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6228 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6229 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6230 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6231 ok(!!d3d, "Failed to create a D3D object.\n");
6232 if (!(device = create_device(d3d, window, window, TRUE)))
6234 skip("Failed to create a D3D device, skipping tests.\n");
6235 goto done;
6238 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6239 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6240 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6242 skip("No ps_1_4 support, skipping tests.\n");
6243 IDirect3DDevice9_Release(device);
6244 goto done;
6247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6248 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6250 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6251 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6252 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6253 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6254 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6255 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6256 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6257 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6258 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6259 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6260 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6261 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6262 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6263 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6264 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6265 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6266 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6267 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6268 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6269 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6270 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6271 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6272 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6273 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6275 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6276 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6277 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6278 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6279 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6280 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6282 hr = IDirect3DDevice9_BeginScene(device);
6283 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6284 if(SUCCEEDED(hr))
6286 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6287 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6289 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6291 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6292 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6294 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6296 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6297 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6299 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6301 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6302 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6304 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6306 hr = IDirect3DDevice9_EndScene(device);
6307 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6310 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6313 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6314 color = getPixelColor(device, 158, 118);
6315 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6316 color = getPixelColor(device, 162, 118);
6317 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6318 color = getPixelColor(device, 158, 122);
6319 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6320 color = getPixelColor(device, 162, 122);
6321 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6323 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6324 color = getPixelColor(device, 158, 358);
6325 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6326 color = getPixelColor(device, 162, 358);
6327 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6328 color = getPixelColor(device, 158, 362);
6329 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6330 color = getPixelColor(device, 162, 362);
6331 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6333 /* 1.2 shader */
6334 color = getPixelColor(device, 478, 358);
6335 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6336 color = getPixelColor(device, 482, 358);
6337 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6338 color = getPixelColor(device, 478, 362);
6339 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6340 color = getPixelColor(device, 482, 362);
6341 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6343 /* 1.3 shader */
6344 color = getPixelColor(device, 478, 118);
6345 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6346 color = getPixelColor(device, 482, 118);
6347 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6348 color = getPixelColor(device, 478, 122);
6349 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6350 color = getPixelColor(device, 482, 122);
6351 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6353 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6358 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6359 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6360 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6361 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6363 hr = IDirect3DDevice9_BeginScene(device);
6364 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6365 if(SUCCEEDED(hr))
6367 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6368 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6370 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6372 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6373 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6375 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6377 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6378 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6380 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6382 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6383 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6385 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6387 hr = IDirect3DDevice9_EndScene(device);
6388 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6391 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6392 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6394 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6395 * that we swapped the values in c1 and c2 to make the other tests return some color
6397 color = getPixelColor(device, 158, 118);
6398 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6399 color = getPixelColor(device, 162, 118);
6400 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6401 color = getPixelColor(device, 158, 122);
6402 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6403 color = getPixelColor(device, 162, 122);
6404 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6406 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6407 * (The Win7 nvidia driver always selects c2)
6409 color = getPixelColor(device, 158, 358);
6410 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6411 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6412 color = getPixelColor(device, 162, 358);
6413 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6414 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6415 color = getPixelColor(device, 158, 362);
6416 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6417 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6418 color = getPixelColor(device, 162, 362);
6419 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6420 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6422 /* 1.2 shader */
6423 color = getPixelColor(device, 478, 358);
6424 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6425 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6426 color = getPixelColor(device, 482, 358);
6427 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6428 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6429 color = getPixelColor(device, 478, 362);
6430 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6431 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6432 color = getPixelColor(device, 482, 362);
6433 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6434 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6436 /* 1.3 shader */
6437 color = getPixelColor(device, 478, 118);
6438 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6439 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6440 color = getPixelColor(device, 482, 118);
6441 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6442 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6443 color = getPixelColor(device, 478, 122);
6444 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6445 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6446 color = getPixelColor(device, 482, 122);
6447 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6448 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6450 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6451 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6453 /* Retest with the coissue flag on the alpha instruction instead. This
6454 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6455 * the same as coissue on .rgb. */
6456 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6457 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6459 hr = IDirect3DDevice9_BeginScene(device);
6460 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6461 if(SUCCEEDED(hr))
6463 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6464 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6466 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6468 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6469 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6471 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6473 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6474 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6475 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6476 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6478 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6479 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6481 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6483 hr = IDirect3DDevice9_EndScene(device);
6484 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6487 /* 1.4 shader */
6488 color = getPixelColor(device, 158, 118);
6489 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6490 color = getPixelColor(device, 162, 118);
6491 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6492 color = getPixelColor(device, 158, 122);
6493 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6494 color = getPixelColor(device, 162, 122);
6495 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6497 /* 1.1 shader */
6498 color = getPixelColor(device, 238, 358);
6499 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6500 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6501 color = getPixelColor(device, 242, 358);
6502 ok(color_match(color, 0x00000000, 1),
6503 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6504 color = getPixelColor(device, 238, 362);
6505 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6506 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6507 color = getPixelColor(device, 242, 362);
6508 ok(color_match(color, 0x00000000, 1),
6509 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6511 /* 1.2 shader */
6512 color = getPixelColor(device, 558, 358);
6513 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6514 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6515 color = getPixelColor(device, 562, 358);
6516 ok(color_match(color, 0x00000000, 1),
6517 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6518 color = getPixelColor(device, 558, 362);
6519 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6520 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6521 color = getPixelColor(device, 562, 362);
6522 ok(color_match(color, 0x00000000, 1),
6523 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6525 /* 1.3 shader */
6526 color = getPixelColor(device, 558, 118);
6527 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6528 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6529 color = getPixelColor(device, 562, 118);
6530 ok(color_match(color, 0x00000000, 1),
6531 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6532 color = getPixelColor(device, 558, 122);
6533 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6534 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6535 color = getPixelColor(device, 562, 122);
6536 ok(color_match(color, 0x00000000, 1),
6537 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6539 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6540 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6542 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6543 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6544 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6545 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6546 IDirect3DPixelShader9_Release(shader_14_coissue);
6547 IDirect3DPixelShader9_Release(shader_13_coissue);
6548 IDirect3DPixelShader9_Release(shader_12_coissue);
6549 IDirect3DPixelShader9_Release(shader_11_coissue);
6550 IDirect3DPixelShader9_Release(shader_14);
6551 IDirect3DPixelShader9_Release(shader_13);
6552 IDirect3DPixelShader9_Release(shader_12);
6553 IDirect3DPixelShader9_Release(shader_11);
6554 refcount = IDirect3DDevice9_Release(device);
6555 ok(!refcount, "Device has %u references left.\n", refcount);
6556 done:
6557 IDirect3D9_Release(d3d);
6558 DestroyWindow(window);
6561 static void nested_loop_test(void)
6563 IDirect3DVertexShader9 *vshader;
6564 IDirect3DPixelShader9 *shader;
6565 IDirect3DDevice9 *device;
6566 IDirect3D9 *d3d;
6567 ULONG refcount;
6568 D3DCAPS9 caps;
6569 DWORD color;
6570 HWND window;
6571 HRESULT hr;
6573 static const DWORD shader_code[] =
6575 0xffff0300, /* ps_3_0 */
6576 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6577 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6578 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
6579 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6580 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6581 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6582 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6583 0x0000001d, /* endloop */
6584 0x0000001d, /* endloop */
6585 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6586 0x0000ffff /* end */
6588 static const DWORD vshader_code[] =
6590 0xfffe0300, /* vs_3_0 */
6591 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6592 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6593 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6594 0x0000ffff /* end */
6596 static const float quad[] =
6598 -1.0f, -1.0f, 0.1f,
6599 -1.0f, 1.0f, 0.1f,
6600 1.0f, -1.0f, 0.1f,
6601 1.0f, 1.0f, 0.1f,
6604 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6605 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6606 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6607 ok(!!d3d, "Failed to create a D3D object.\n");
6608 if (!(device = create_device(d3d, window, window, TRUE)))
6610 skip("Failed to create a D3D device, skipping tests.\n");
6611 goto done;
6614 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6615 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6616 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6618 skip("No shader model 3 support, skipping tests.\n");
6619 IDirect3DDevice9_Release(device);
6620 goto done;
6623 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6624 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6625 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6626 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6627 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6628 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6629 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6630 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6632 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6633 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
6634 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6636 hr = IDirect3DDevice9_BeginScene(device);
6637 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6638 if(SUCCEEDED(hr))
6640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6641 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6642 hr = IDirect3DDevice9_EndScene(device);
6643 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6646 color = getPixelColor(device, 360, 240);
6647 ok(color_match(color, 0x00800000, 1),
6648 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
6650 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6651 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6653 IDirect3DPixelShader9_Release(shader);
6654 IDirect3DVertexShader9_Release(vshader);
6655 refcount = IDirect3DDevice9_Release(device);
6656 ok(!refcount, "Device has %u references left.\n", refcount);
6657 done:
6658 IDirect3D9_Release(d3d);
6659 DestroyWindow(window);
6662 static void pretransformed_varying_test(void)
6664 /* dcl_position: fails to compile */
6665 static const DWORD blendweight_code[] =
6667 0xffff0300, /* ps_3_0 */
6668 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6669 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6670 0x0000ffff /* end */
6672 static const DWORD blendindices_code[] =
6674 0xffff0300, /* ps_3_0 */
6675 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6676 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6677 0x0000ffff /* end */
6679 static const DWORD normal_code[] =
6681 0xffff0300, /* ps_3_0 */
6682 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6683 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6684 0x0000ffff /* end */
6686 /* psize: fails? */
6687 static const DWORD texcoord0_code[] =
6689 0xffff0300, /* ps_3_0 */
6690 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6691 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6692 0x0000ffff /* end */
6694 static const DWORD tangent_code[] =
6696 0xffff0300, /* ps_3_0 */
6697 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6698 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6699 0x0000ffff /* end */
6701 static const DWORD binormal_code[] =
6703 0xffff0300, /* ps_3_0 */
6704 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6705 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6706 0x0000ffff /* end */
6708 /* tessfactor: fails */
6709 /* positiont: fails */
6710 static const DWORD color_code[] =
6712 0xffff0300, /* ps_3_0 */
6713 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6714 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6715 0x0000ffff /* end */
6717 static const DWORD fog_code[] =
6719 0xffff0300, /* ps_3_0 */
6720 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
6721 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6722 0x0000ffff /* end */
6724 static const DWORD depth_code[] =
6726 0xffff0300, /* ps_3_0 */
6727 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
6728 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6729 0x0000ffff /* end */
6731 static const DWORD specular_code[] =
6733 0xffff0300, /* ps_3_0 */
6734 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
6735 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6736 0x0000ffff /* end */
6738 /* sample: fails */
6740 static const struct
6742 const char *name;
6743 const DWORD *shader_code;
6744 DWORD color;
6745 BOOL todo;
6747 tests[] =
6749 {"blendweight", blendweight_code, 0x00191919, TRUE },
6750 {"blendindices", blendindices_code, 0x00333333, TRUE },
6751 {"normal", normal_code, 0x004c4c4c, TRUE },
6752 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
6753 {"tangent", tangent_code, 0x00999999, TRUE },
6754 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
6755 {"color", color_code, 0x00e6e6e6, FALSE},
6756 {"fog", fog_code, 0x00666666, TRUE },
6757 {"depth", depth_code, 0x00cccccc, TRUE },
6758 {"specular", specular_code, 0x004488ff, FALSE},
6760 /* Declare a monster vertex type :-) */
6761 static const D3DVERTEXELEMENT9 decl_elements[] = {
6762 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6763 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
6764 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
6765 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
6766 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
6767 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6768 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
6769 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
6770 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
6771 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6772 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
6773 D3DDECL_END()
6776 static const struct
6778 float pos_x, pos_y, pos_z, rhw;
6779 float weight_1, weight_2, weight_3, weight_4;
6780 float index_1, index_2, index_3, index_4;
6781 float normal_1, normal_2, normal_3, normal_4;
6782 float fog_1, fog_2, fog_3, fog_4;
6783 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
6784 float tangent_1, tangent_2, tangent_3, tangent_4;
6785 float binormal_1, binormal_2, binormal_3, binormal_4;
6786 float depth_1, depth_2, depth_3, depth_4;
6787 D3DCOLOR diffuse;
6788 D3DCOLOR specular;
6790 data[] =
6793 0.0f, 0.0f, 0.1f, 1.0f,
6794 0.1f, 0.1f, 0.1f, 0.1f,
6795 0.2f, 0.2f, 0.2f, 0.2f,
6796 0.3f, 0.3f, 0.3f, 0.3f,
6797 0.4f, 0.4f, 0.4f, 0.4f,
6798 0.5f, 0.55f, 0.55f, 0.55f,
6799 0.6f, 0.6f, 0.6f, 0.7f,
6800 0.7f, 0.7f, 0.7f, 0.6f,
6801 0.8f, 0.8f, 0.8f, 0.8f,
6802 0xe6e6e6e6, /* 0.9 * 256 */
6803 0x224488ff, /* Nothing special */
6806 640.0f, 0.0f, 0.1f, 1.0f,
6807 0.1f, 0.1f, 0.1f, 0.1f,
6808 0.2f, 0.2f, 0.2f, 0.2f,
6809 0.3f, 0.3f, 0.3f, 0.3f,
6810 0.4f, 0.4f, 0.4f, 0.4f,
6811 0.5f, 0.55f, 0.55f, 0.55f,
6812 0.6f, 0.6f, 0.6f, 0.7f,
6813 0.7f, 0.7f, 0.7f, 0.6f,
6814 0.8f, 0.8f, 0.8f, 0.8f,
6815 0xe6e6e6e6, /* 0.9 * 256 */
6816 0x224488ff, /* Nothing special */
6819 0.0f, 480.0f, 0.1f, 1.0f,
6820 0.1f, 0.1f, 0.1f, 0.1f,
6821 0.2f, 0.2f, 0.2f, 0.2f,
6822 0.3f, 0.3f, 0.3f, 0.3f,
6823 0.4f, 0.4f, 0.4f, 0.4f,
6824 0.5f, 0.55f, 0.55f, 0.55f,
6825 0.6f, 0.6f, 0.6f, 0.7f,
6826 0.7f, 0.7f, 0.7f, 0.6f,
6827 0.8f, 0.8f, 0.8f, 0.8f,
6828 0xe6e6e6e6, /* 0.9 * 256 */
6829 0x224488ff, /* Nothing special */
6832 640.0f, 480.0f, 0.1f, 1.0f,
6833 0.1f, 0.1f, 0.1f, 0.1f,
6834 0.2f, 0.2f, 0.2f, 0.2f,
6835 0.3f, 0.3f, 0.3f, 0.3f,
6836 0.4f, 0.4f, 0.4f, 0.4f,
6837 0.5f, 0.55f, 0.55f, 0.55f,
6838 0.6f, 0.6f, 0.6f, 0.7f,
6839 0.7f, 0.7f, 0.7f, 0.6f,
6840 0.8f, 0.8f, 0.8f, 0.8f,
6841 0xe6e6e6e6, /* 0.9 * 256 */
6842 0x224488ff, /* Nothing special */
6845 IDirect3DVertexDeclaration9 *decl;
6846 IDirect3DDevice9 *device;
6847 IDirect3D9 *d3d;
6848 unsigned int i;
6849 ULONG refcount;
6850 D3DCAPS9 caps;
6851 DWORD color;
6852 HWND window;
6853 HRESULT hr;
6855 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6856 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6857 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6858 ok(!!d3d, "Failed to create a D3D object.\n");
6859 if (!(device = create_device(d3d, window, window, TRUE)))
6861 skip("Failed to create a D3D device, skipping tests.\n");
6862 goto done;
6865 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6866 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6867 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6869 skip("No shader model 3 support, skipping tests.\n");
6870 IDirect3DDevice9_Release(device);
6871 goto done;
6874 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6875 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6876 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6877 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6879 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6880 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6881 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6883 IDirect3DPixelShader9 *shader;
6885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
6886 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6888 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
6889 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
6891 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6892 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6894 hr = IDirect3DDevice9_BeginScene(device);
6895 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6896 if(SUCCEEDED(hr))
6898 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
6899 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6900 hr = IDirect3DDevice9_EndScene(device);
6901 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6904 /* This isn't a weekend's job to fix, ignore the problem for now.
6905 * Needs a replacement pipeline. */
6906 color = getPixelColor(device, 360, 240);
6907 if (tests[i].todo)
6908 todo_wine ok(color_match(color, tests[i].color, 1)
6909 || broken(color_match(color, 0x00000000, 1)
6910 && tests[i].shader_code == blendindices_code),
6911 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
6912 tests[i].name, color, tests[i].color);
6913 else
6914 ok(color_match(color, tests[i].color, 1),
6915 "Test %s returned color 0x%08x, expected 0x%08x.\n",
6916 tests[i].name, color, tests[i].color);
6918 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6919 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6921 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6922 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
6923 IDirect3DPixelShader9_Release(shader);
6926 IDirect3DVertexDeclaration9_Release(decl);
6927 refcount = IDirect3DDevice9_Release(device);
6928 ok(!refcount, "Device has %u references left.\n", refcount);
6929 done:
6930 IDirect3D9_Release(d3d);
6931 DestroyWindow(window);
6934 static void test_compare_instructions(void)
6936 IDirect3DVertexShader9 *shader_slt_scalar;
6937 IDirect3DVertexShader9 *shader_sge_scalar;
6938 IDirect3DVertexShader9 *shader_slt_vec;
6939 IDirect3DVertexShader9 *shader_sge_vec;
6940 IDirect3DDevice9 *device;
6941 IDirect3D9 *d3d;
6942 D3DCOLOR color;
6943 ULONG refcount;
6944 D3DCAPS9 caps;
6945 HWND window;
6946 HRESULT hr;
6948 static const DWORD shader_sge_vec_code[] =
6950 0xfffe0101, /* vs_1_1 */
6951 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6952 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6953 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6954 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6955 0x0000ffff /* end */
6957 static const DWORD shader_slt_vec_code[] =
6959 0xfffe0101, /* vs_1_1 */
6960 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6961 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6962 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6963 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6964 0x0000ffff /* end */
6966 static const DWORD shader_sge_scalar_code[] =
6968 0xfffe0101, /* vs_1_1 */
6969 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6970 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6971 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6972 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6973 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6974 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6975 0x0000ffff /* end */
6977 static const DWORD shader_slt_scalar_code[] =
6979 0xfffe0101, /* vs_1_1 */
6980 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6981 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6982 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6983 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6984 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6985 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6986 0x0000ffff /* end */
6988 static const float quad1[] =
6990 -1.0f, -1.0f, 0.1f,
6991 -1.0f, 0.0f, 0.1f,
6992 0.0f, -1.0f, 0.1f,
6993 0.0f, 0.0f, 0.1f,
6995 static const float quad2[] =
6997 0.0f, -1.0f, 0.1f,
6998 0.0f, 0.0f, 0.1f,
6999 1.0f, -1.0f, 0.1f,
7000 1.0f, 0.0f, 0.1f,
7002 static const float quad3[] =
7004 -1.0f, 0.0f, 0.1f,
7005 -1.0f, 1.0f, 0.1f,
7006 0.0f, 0.0f, 0.1f,
7007 0.0f, 1.0f, 0.1f,
7009 static const float quad4[] =
7011 0.0f, 0.0f, 0.1f,
7012 0.0f, 1.0f, 0.1f,
7013 1.0f, 0.0f, 0.1f,
7014 1.0f, 1.0f, 0.1f,
7016 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7017 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7019 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7020 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7021 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7022 ok(!!d3d, "Failed to create a D3D object.\n");
7023 if (!(device = create_device(d3d, window, window, TRUE)))
7025 skip("Failed to create a D3D device, skipping tests.\n");
7026 goto done;
7029 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7030 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7031 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7033 skip("No vs_1_1 support, skipping tests.\n");
7034 IDirect3DDevice9_Release(device);
7035 goto done;
7038 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7039 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7041 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7042 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7043 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7044 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7045 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7046 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7047 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7048 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7049 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7050 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7051 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7052 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7053 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7054 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7056 hr = IDirect3DDevice9_BeginScene(device);
7057 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7058 if(SUCCEEDED(hr))
7060 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7063 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7065 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7066 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7067 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7068 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7070 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7071 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7073 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7075 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7076 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7078 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7079 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7081 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7083 hr = IDirect3DDevice9_EndScene(device);
7084 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7087 color = getPixelColor(device, 160, 360);
7088 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7089 color = getPixelColor(device, 480, 360);
7090 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7091 color = getPixelColor(device, 160, 120);
7092 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7093 color = getPixelColor(device, 480, 160);
7094 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7096 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7097 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7099 IDirect3DVertexShader9_Release(shader_sge_vec);
7100 IDirect3DVertexShader9_Release(shader_slt_vec);
7101 IDirect3DVertexShader9_Release(shader_sge_scalar);
7102 IDirect3DVertexShader9_Release(shader_slt_scalar);
7103 refcount = IDirect3DDevice9_Release(device);
7104 ok(!refcount, "Device has %u references left.\n", refcount);
7105 done:
7106 IDirect3D9_Release(d3d);
7107 DestroyWindow(window);
7110 static void test_vshader_input(void)
7112 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7113 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7114 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7115 D3DADAPTER_IDENTIFIER9 identifier;
7116 IDirect3DPixelShader9 *ps;
7117 IDirect3DDevice9 *device;
7118 IDirect3D9 *d3d;
7119 ULONG refcount;
7120 unsigned int i;
7121 D3DCAPS9 caps;
7122 DWORD color;
7123 HWND window;
7124 HRESULT hr;
7125 BOOL warp;
7127 static const DWORD swapped_shader_code_3[] =
7129 0xfffe0300, /* vs_3_0 */
7130 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7131 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7132 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7133 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7134 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7135 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7136 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7137 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7138 0x0000ffff /* end */
7140 static const DWORD swapped_shader_code_1[] =
7142 0xfffe0101, /* vs_1_1 */
7143 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7144 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7145 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7146 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7147 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7148 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7149 0x0000ffff /* end */
7151 static const DWORD swapped_shader_code_2[] =
7153 0xfffe0200, /* vs_2_0 */
7154 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7155 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7156 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7157 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7158 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7159 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7160 0x0000ffff /* end */
7162 static const DWORD texcoord_color_shader_code_3[] =
7164 0xfffe0300, /* vs_3_0 */
7165 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7166 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7167 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7168 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7169 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7170 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7171 0x0000ffff /* end */
7173 static const DWORD texcoord_color_shader_code_2[] =
7175 0xfffe0200, /* vs_2_0 */
7176 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7177 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7178 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7179 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7180 0x0000ffff /* end */
7182 static const DWORD texcoord_color_shader_code_1[] =
7184 0xfffe0101, /* vs_1_1 */
7185 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7186 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7187 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7188 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7189 0x0000ffff /* end */
7191 static const DWORD color_color_shader_code_3[] =
7193 0xfffe0300, /* vs_3_0 */
7194 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7195 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7196 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7197 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7198 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7199 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7200 0x0000ffff /* end */
7202 static const DWORD color_color_shader_code_2[] =
7204 0xfffe0200, /* vs_2_0 */
7205 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7206 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7207 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7208 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7209 0x0000ffff /* end */
7211 static const DWORD color_color_shader_code_1[] =
7213 0xfffe0101, /* vs_1_1 */
7214 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7215 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7216 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7217 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7218 0x0000ffff /* end */
7220 static const DWORD ps3_code[] =
7222 0xffff0300, /* ps_3_0 */
7223 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7224 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7225 0x0000ffff /* end */
7227 static const float quad1[] =
7229 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7230 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7231 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7232 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7234 static const float quad2[] =
7236 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7237 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7238 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7239 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7241 static const float quad3[] =
7243 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7244 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7245 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7246 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7248 static const float quad4[] =
7250 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7251 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7252 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7253 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7255 static const float quad1_modified[] =
7257 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7258 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7259 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7260 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7262 static const float quad2_modified[] =
7264 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7265 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7266 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7267 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7269 static const struct vertex quad1_color[] =
7271 {-1.0f, -1.0f, 0.1f, 0x00ff8040},
7272 {-1.0f, 0.0f, 0.1f, 0x00ff8040},
7273 { 0.0f, -1.0f, 0.1f, 0x00ff8040},
7274 { 0.0f, 0.0f, 0.1f, 0x00ff8040},
7276 static const struct vertex quad2_color[] =
7278 { 0.0f, -1.0f, 0.1f, 0x00ff8040},
7279 { 0.0f, 0.0f, 0.1f, 0x00ff8040},
7280 { 1.0f, -1.0f, 0.1f, 0x00ff8040},
7281 { 1.0f, 0.0f, 0.1f, 0x00ff8040},
7283 static const struct vertex quad3_color[] =
7285 {-1.0f, 0.0f, 0.1f, 0x00ff8040},
7286 {-1.0f, 1.0f, 0.1f, 0x00ff8040},
7287 { 0.0f, 0.0f, 0.1f, 0x00ff8040},
7288 { 0.0f, 1.0f, 0.1f, 0x00ff8040},
7290 static const float quad4_color[] =
7292 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7293 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7294 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7295 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7297 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7299 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7300 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7301 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7302 D3DDECL_END()
7304 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7306 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7307 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7308 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7309 D3DDECL_END()
7311 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7313 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7314 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7315 D3DDECL_END()
7317 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7319 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7320 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7321 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7322 D3DDECL_END()
7324 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7326 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7327 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7328 D3DDECL_END()
7330 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7332 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7333 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7334 D3DDECL_END()
7336 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7338 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7339 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7340 D3DDECL_END()
7342 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7344 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7345 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7346 D3DDECL_END()
7348 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7349 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7351 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7352 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7353 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7354 ok(!!d3d, "Failed to create a D3D object.\n");
7355 if (!(device = create_device(d3d, window, window, TRUE)))
7357 skip("Failed to create a D3D device, skipping tests.\n");
7358 goto done;
7361 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7362 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7363 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7365 skip("No vs_3_0 support, skipping tests.\n");
7366 IDirect3DDevice9_Release(device);
7367 goto done;
7370 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7371 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7372 warp = !strcmp(identifier.Description, "Microsoft Basic Render Driver");
7374 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7375 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7376 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7377 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7378 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7379 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7380 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7381 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7383 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7385 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7386 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7387 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7388 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7389 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7390 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7392 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7395 for (i = 1; i <= 3; ++i)
7397 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7398 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7399 if(i == 3) {
7400 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7401 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7402 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7404 } else if(i == 2){
7405 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7406 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7407 } else if(i == 1) {
7408 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7409 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7412 hr = IDirect3DDevice9_BeginScene(device);
7413 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7414 if(SUCCEEDED(hr))
7416 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7417 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7419 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7420 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7422 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7424 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7425 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7427 if(i == 3 || i == 2) {
7428 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7429 } else if(i == 1) {
7430 /* Succeeds or fails, depending on SW or HW vertex processing */
7431 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
7434 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7435 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7436 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7437 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7439 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7440 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7442 if(i == 3 || i == 2) {
7443 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7444 } else if(i == 1) {
7445 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
7448 hr = IDirect3DDevice9_EndScene(device);
7449 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7452 if(i == 3 || i == 2) {
7453 color = getPixelColor(device, 160, 360);
7454 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7455 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7457 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7458 color = getPixelColor(device, 480, 360);
7459 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7460 * mostly random data as input. */
7461 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7462 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7463 color = getPixelColor(device, 160, 120);
7464 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7465 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7466 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7468 color = getPixelColor(device, 480, 160);
7469 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7470 } else if(i == 1) {
7471 color = getPixelColor(device, 160, 360);
7472 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7473 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7474 color = getPixelColor(device, 480, 360);
7475 /* Accept the clear color as well in this case, since SW VP
7476 * returns an error. On the Windows 8 testbot (WARP) the draw
7477 * succeeds, but uses mostly random data as input. */
7478 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7479 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7480 color = getPixelColor(device, 160, 120);
7481 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7482 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7483 color = getPixelColor(device, 480, 160);
7484 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7488 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7493 /* Now find out if the whole streams are re-read, or just the last active value for the
7494 * vertices is used.
7496 hr = IDirect3DDevice9_BeginScene(device);
7497 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7498 if(SUCCEEDED(hr))
7500 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7501 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7503 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7504 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7506 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7508 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7509 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7511 if(i == 3 || i == 2) {
7512 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7513 } else if(i == 1) {
7514 /* Succeeds or fails, depending on SW or HW vertex processing */
7515 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
7518 hr = IDirect3DDevice9_EndScene(device);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7522 color = getPixelColor(device, 480, 350);
7523 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7524 * as well.
7526 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7527 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7528 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7529 * refrast's result.
7531 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7533 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7534 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7535 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7537 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7538 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7540 IDirect3DDevice9_SetVertexShader(device, NULL);
7541 IDirect3DDevice9_SetPixelShader(device, NULL);
7542 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7544 IDirect3DVertexShader9_Release(swapped_shader);
7547 for (i = 1; i <= 3; ++i)
7549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7550 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7551 if(i == 3) {
7552 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
7553 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7554 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
7555 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7556 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7557 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7558 } else if(i == 2){
7559 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
7560 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7561 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
7562 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7563 } else if(i == 1) {
7564 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
7565 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7566 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
7567 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7570 hr = IDirect3DDevice9_BeginScene(device);
7571 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7572 if(SUCCEEDED(hr))
7574 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
7575 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7576 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
7577 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7579 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7581 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
7582 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7584 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
7585 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7586 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
7587 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7589 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7591 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
7592 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7593 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
7594 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7596 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7598 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
7599 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7600 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7601 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7603 hr = IDirect3DDevice9_EndScene(device);
7604 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7606 IDirect3DDevice9_SetVertexShader(device, NULL);
7607 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7608 IDirect3DDevice9_SetPixelShader(device, NULL);
7610 color = getPixelColor(device, 160, 360);
7611 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7612 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7613 color = getPixelColor(device, 480, 360);
7614 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7615 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7616 color = getPixelColor(device, 160, 120);
7617 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7618 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7619 color = getPixelColor(device, 480, 160);
7620 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7621 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7626 IDirect3DVertexShader9_Release(texcoord_color_shader);
7627 IDirect3DVertexShader9_Release(color_color_shader);
7630 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
7631 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
7632 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
7633 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
7635 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
7636 IDirect3DVertexDeclaration9_Release(decl_color_color);
7637 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
7638 IDirect3DVertexDeclaration9_Release(decl_color_float);
7640 IDirect3DPixelShader9_Release(ps);
7641 refcount = IDirect3DDevice9_Release(device);
7642 ok(!refcount, "Device has %u references left.\n", refcount);
7643 done:
7644 IDirect3D9_Release(d3d);
7645 DestroyWindow(window);
7648 static void srgbtexture_test(IDirect3DDevice9 *device)
7650 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
7651 * texture stage state to render a quad using that texture. The resulting
7652 * color components should be 0x36 (~ 0.21), per this formula:
7653 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
7654 * This is true where srgb_color > 0.04045. */
7655 struct IDirect3DTexture9 *texture = NULL;
7656 struct IDirect3DSurface9 *surface = NULL;
7657 IDirect3D9 *d3d = NULL;
7658 HRESULT hr;
7659 D3DLOCKED_RECT lr;
7660 DWORD color;
7661 float quad[] = {
7662 -1.0, 1.0, 0.0, 0.0, 0.0,
7663 1.0, 1.0, 0.0, 1.0, 0.0,
7664 -1.0, -1.0, 0.0, 0.0, 1.0,
7665 1.0, -1.0, 0.0, 1.0, 1.0,
7669 memset(&lr, 0, sizeof(lr));
7670 IDirect3DDevice9_GetDirect3D(device, &d3d);
7671 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7672 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
7673 D3DFMT_A8R8G8B8) != D3D_OK) {
7674 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
7675 goto out;
7678 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
7679 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
7680 &texture, NULL);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
7682 if(!texture) {
7683 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
7684 goto out;
7686 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7687 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
7689 fill_surface(surface, 0xff7f7f7f, 0);
7690 IDirect3DSurface9_Release(surface);
7692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7694 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7697 hr = IDirect3DDevice9_BeginScene(device);
7698 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7699 if(SUCCEEDED(hr))
7701 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
7702 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7705 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
7709 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
7711 hr = IDirect3DDevice9_EndScene(device);
7712 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7715 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7717 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7718 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7720 color = getPixelColor(device, 320, 240);
7721 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
7723 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7724 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7726 out:
7727 if(texture) IDirect3DTexture9_Release(texture);
7728 IDirect3D9_Release(d3d);
7731 static void shademode_test(IDirect3DDevice9 *device)
7733 /* Render a quad and try all of the different fixed function shading models. */
7734 struct IDirect3DVertexBuffer9 *vb_strip = NULL;
7735 struct IDirect3DVertexBuffer9 *vb_list = NULL;
7736 HRESULT hr;
7737 DWORD color0, color1;
7738 DWORD color0_gouraud = 0, color1_gouraud = 0;
7739 DWORD shademode = D3DSHADE_FLAT;
7740 DWORD primtype = D3DPT_TRIANGLESTRIP;
7741 void *data = NULL;
7742 UINT i, j;
7743 struct vertex quad_strip[] =
7745 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7746 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7747 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7748 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7750 struct vertex quad_list[] =
7752 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7753 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7754 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7756 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7757 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7758 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7761 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7762 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7763 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7764 if (FAILED(hr)) goto bail;
7766 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7767 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7768 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7769 if (FAILED(hr)) goto bail;
7771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7772 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7774 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7775 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7777 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7778 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7779 memcpy(data, quad_strip, sizeof(quad_strip));
7780 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7781 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7783 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7784 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7785 memcpy(data, quad_list, sizeof(quad_list));
7786 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7787 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7789 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
7790 * the color fixups we have to do for FLAT shading will be dependent on that. */
7791 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7792 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7794 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7795 for (j=0; j<2; j++) {
7797 /* Inner loop just changes the D3DRS_SHADEMODE */
7798 for (i=0; i<3; i++) {
7799 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7800 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7805 hr = IDirect3DDevice9_BeginScene(device);
7806 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7807 if(SUCCEEDED(hr))
7809 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7810 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7812 hr = IDirect3DDevice9_EndScene(device);
7813 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7816 /* Sample two spots from the output */
7817 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7818 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7819 switch(shademode) {
7820 case D3DSHADE_FLAT:
7821 /* Should take the color of the first vertex of each triangle */
7822 if (0)
7824 /* This test depends on EXT_provoking_vertex being
7825 * available. This extension is currently (20090810)
7826 * not common enough to let the test fail if it isn't
7827 * present. */
7828 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7829 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7831 shademode = D3DSHADE_GOURAUD;
7832 break;
7833 case D3DSHADE_GOURAUD:
7834 /* Should be an interpolated blend */
7836 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7837 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7838 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7839 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7841 color0_gouraud = color0;
7842 color1_gouraud = color1;
7844 shademode = D3DSHADE_PHONG;
7845 break;
7846 case D3DSHADE_PHONG:
7847 /* Should be the same as GOURAUD, since no hardware implements this */
7848 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7849 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7850 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7851 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7853 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7854 color0_gouraud, color0);
7855 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7856 color1_gouraud, color1);
7857 break;
7861 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7862 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7864 /* Now, do it all over again with a TRIANGLELIST */
7865 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7866 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7867 primtype = D3DPT_TRIANGLELIST;
7868 shademode = D3DSHADE_FLAT;
7871 bail:
7872 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7873 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7875 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7877 if (vb_strip)
7878 IDirect3DVertexBuffer9_Release(vb_strip);
7879 if (vb_list)
7880 IDirect3DVertexBuffer9_Release(vb_list);
7883 static void alpha_test(IDirect3DDevice9 *device)
7885 HRESULT hr;
7886 IDirect3DTexture9 *offscreenTexture;
7887 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7888 DWORD color;
7890 struct vertex quad1[] =
7892 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7893 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7894 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7895 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7897 struct vertex quad2[] =
7899 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7900 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7901 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7902 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7904 static const float composite_quad[][5] = {
7905 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7906 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7907 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7908 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7911 /* Clear the render target with alpha = 0.5 */
7912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7913 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7915 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7916 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7918 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7919 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7920 if(!backbuffer) {
7921 goto out;
7924 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7925 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7926 if(!offscreen) {
7927 goto out;
7930 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7931 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7933 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7934 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7935 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7936 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7937 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7938 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7939 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7940 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7942 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7945 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7946 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7948 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7950 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7952 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7954 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7957 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7959 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7961 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7963 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7964 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7965 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7966 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7967 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7969 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7972 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7974 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7976 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7979 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7981 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7983 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7985 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7986 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7988 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7989 * Disable alpha blending for the final composition
7991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7992 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7993 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7994 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7996 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7997 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7999 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8000 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8001 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
8003 hr = IDirect3DDevice9_EndScene(device);
8004 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
8007 color = getPixelColor(device, 160, 360);
8008 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8009 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8011 color = getPixelColor(device, 160, 120);
8012 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8013 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8015 color = getPixelColor(device, 480, 360);
8016 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8017 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8019 color = getPixelColor(device, 480, 120);
8020 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8021 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8023 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8025 out:
8026 /* restore things */
8027 if(backbuffer) {
8028 IDirect3DSurface9_Release(backbuffer);
8030 if(offscreenTexture) {
8031 IDirect3DTexture9_Release(offscreenTexture);
8033 if(offscreen) {
8034 IDirect3DSurface9_Release(offscreen);
8038 struct vertex_shortcolor {
8039 float x, y, z;
8040 unsigned short r, g, b, a;
8042 struct vertex_floatcolor {
8043 float x, y, z;
8044 float r, g, b, a;
8047 static void fixed_function_decl_test(void)
8049 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8050 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
8051 IDirect3DVertexBuffer9 *vb, *vb2;
8052 IDirect3DDevice9 *device;
8053 BOOL s_ok, ub_ok, f_ok;
8054 DWORD color, size, i;
8055 IDirect3D9 *d3d;
8056 ULONG refcount;
8057 D3DCAPS9 caps;
8058 HWND window;
8059 void *data;
8060 HRESULT hr;
8062 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8063 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8064 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8065 D3DDECL_END()
8067 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8068 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8069 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8070 D3DDECL_END()
8072 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8073 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8074 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8075 D3DDECL_END()
8077 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8078 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8079 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8080 D3DDECL_END()
8082 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8083 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8084 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8085 D3DDECL_END()
8087 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8088 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8089 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8090 D3DDECL_END()
8092 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8093 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8094 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8095 D3DDECL_END()
8097 static const struct vertex quad1[] = /* D3DCOLOR */
8099 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
8100 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
8101 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
8102 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
8104 static const struct vertex quad2[] = /* UBYTE4N */
8106 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
8107 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
8108 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
8109 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
8111 static const struct vertex_shortcolor quad3[] = /* short */
8113 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8114 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8115 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8116 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8118 static const struct vertex_floatcolor quad4[] =
8120 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8121 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8122 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8123 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8125 static const DWORD colors[] =
8127 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8128 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8129 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8130 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8131 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8132 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8133 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8134 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8135 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8136 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8137 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8138 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8139 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8140 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8141 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8142 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8144 static const float quads[] =
8146 -1.0f, -1.0f, 0.1f,
8147 -1.0f, 0.0f, 0.1f,
8148 0.0f, -1.0f, 0.1f,
8149 0.0f, 0.0f, 0.1f,
8151 0.0f, -1.0f, 0.1f,
8152 0.0f, 0.0f, 0.1f,
8153 1.0f, -1.0f, 0.1f,
8154 1.0f, 0.0f, 0.1f,
8156 0.0f, 0.0f, 0.1f,
8157 0.0f, 1.0f, 0.1f,
8158 1.0f, 0.0f, 0.1f,
8159 1.0f, 1.0f, 0.1f,
8161 -1.0f, 0.0f, 0.1f,
8162 -1.0f, 1.0f, 0.1f,
8163 0.0f, 0.0f, 0.1f,
8164 0.0f, 1.0f, 0.1f,
8166 static const struct tvertex quad_transformed[] =
8168 { 90, 110, 0.1, 2.0, 0x00ffff00},
8169 { 570, 110, 0.1, 2.0, 0x00ffff00},
8170 { 90, 300, 0.1, 2.0, 0x00ffff00},
8171 { 570, 300, 0.1, 2.0, 0x00ffff00}
8174 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8175 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8176 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8177 ok(!!d3d, "Failed to create a D3D object.\n");
8178 if (!(device = create_device(d3d, window, window, TRUE)))
8180 skip("Failed to create a D3D device, skipping tests.\n");
8181 goto done;
8184 memset(&caps, 0, sizeof(caps));
8185 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8186 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8189 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8191 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8192 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8193 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8194 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8195 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8196 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8197 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8198 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8199 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8200 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8201 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8202 } else {
8203 trace("D3DDTCAPS_UBYTE4N not supported\n");
8204 dcl_ubyte_2 = NULL;
8205 dcl_ubyte = NULL;
8207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8208 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8209 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8210 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8212 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8213 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8214 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8215 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8218 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8220 hr = IDirect3DDevice9_BeginScene(device);
8221 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8222 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8223 if(SUCCEEDED(hr)) {
8224 if(dcl_color) {
8225 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8228 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8231 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
8232 * accepts them, the nvidia driver accepts them all. All those differences even though we're
8233 * using software vertex processing. Doh!
8235 if(dcl_ubyte) {
8236 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8238 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8239 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8240 ub_ok = SUCCEEDED(hr);
8243 if(dcl_short) {
8244 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8245 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8247 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8248 s_ok = SUCCEEDED(hr);
8251 if(dcl_float) {
8252 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8253 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8254 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8255 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8256 f_ok = SUCCEEDED(hr);
8259 hr = IDirect3DDevice9_EndScene(device);
8260 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
8263 if(dcl_short) {
8264 color = getPixelColor(device, 480, 360);
8265 ok(color == 0x000000ff || !s_ok,
8266 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8268 if(dcl_ubyte) {
8269 color = getPixelColor(device, 160, 120);
8270 ok(color == 0x0000ffff || !ub_ok,
8271 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8273 if(dcl_color) {
8274 color = getPixelColor(device, 160, 360);
8275 ok(color == 0x00ffff00,
8276 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8278 if(dcl_float) {
8279 color = getPixelColor(device, 480, 120);
8280 ok(color == 0x00ff0000 || !f_ok,
8281 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8283 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8285 /* The following test with vertex buffers doesn't serve to find out new information from windows.
8286 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
8287 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
8288 * whether the immediate mode code works
8290 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8291 hr = IDirect3DDevice9_BeginScene(device);
8292 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8293 if(SUCCEEDED(hr)) {
8294 if(dcl_color) {
8295 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8296 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8297 memcpy(data, quad1, sizeof(quad1));
8298 hr = IDirect3DVertexBuffer9_Unlock(vb);
8299 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8300 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8301 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8302 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8303 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8304 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8305 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8308 if(dcl_ubyte) {
8309 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8310 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8311 memcpy(data, quad2, sizeof(quad2));
8312 hr = IDirect3DVertexBuffer9_Unlock(vb);
8313 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8314 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8315 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8316 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8317 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8318 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8319 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8320 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8321 ub_ok = SUCCEEDED(hr);
8324 if(dcl_short) {
8325 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8326 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8327 memcpy(data, quad3, sizeof(quad3));
8328 hr = IDirect3DVertexBuffer9_Unlock(vb);
8329 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8330 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8331 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8332 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8333 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8334 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8335 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8336 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8337 s_ok = SUCCEEDED(hr);
8340 if(dcl_float) {
8341 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8342 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8343 memcpy(data, quad4, sizeof(quad4));
8344 hr = IDirect3DVertexBuffer9_Unlock(vb);
8345 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8346 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8348 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8349 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8350 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8351 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8352 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8353 f_ok = SUCCEEDED(hr);
8356 hr = IDirect3DDevice9_EndScene(device);
8357 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
8360 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8361 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8362 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8363 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8365 if(dcl_short) {
8366 color = getPixelColor(device, 480, 360);
8367 ok(color == 0x000000ff || !s_ok,
8368 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8370 if(dcl_ubyte) {
8371 color = getPixelColor(device, 160, 120);
8372 ok(color == 0x0000ffff || !ub_ok,
8373 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8375 if(dcl_color) {
8376 color = getPixelColor(device, 160, 360);
8377 ok(color == 0x00ffff00,
8378 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8380 if(dcl_float) {
8381 color = getPixelColor(device, 480, 120);
8382 ok(color == 0x00ff0000 || !f_ok,
8383 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8385 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8388 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8390 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
8391 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8392 memcpy(data, quad_transformed, sizeof(quad_transformed));
8393 hr = IDirect3DVertexBuffer9_Unlock(vb);
8394 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8396 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
8397 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8399 hr = IDirect3DDevice9_BeginScene(device);
8400 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8401 if(SUCCEEDED(hr)) {
8402 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
8403 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8404 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8405 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8407 hr = IDirect3DDevice9_EndScene(device);
8408 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8411 color = getPixelColor(device, 88, 108);
8412 ok(color == 0x000000ff,
8413 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8414 color = getPixelColor(device, 92, 108);
8415 ok(color == 0x000000ff,
8416 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8417 color = getPixelColor(device, 88, 112);
8418 ok(color == 0x000000ff,
8419 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8420 color = getPixelColor(device, 92, 112);
8421 ok(color == 0x00ffff00,
8422 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8424 color = getPixelColor(device, 568, 108);
8425 ok(color == 0x000000ff,
8426 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8427 color = getPixelColor(device, 572, 108);
8428 ok(color == 0x000000ff,
8429 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8430 color = getPixelColor(device, 568, 112);
8431 ok(color == 0x00ffff00,
8432 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8433 color = getPixelColor(device, 572, 112);
8434 ok(color == 0x000000ff,
8435 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8437 color = getPixelColor(device, 88, 298);
8438 ok(color == 0x000000ff,
8439 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8440 color = getPixelColor(device, 92, 298);
8441 ok(color == 0x00ffff00,
8442 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8443 color = getPixelColor(device, 88, 302);
8444 ok(color == 0x000000ff,
8445 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8446 color = getPixelColor(device, 92, 302);
8447 ok(color == 0x000000ff,
8448 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8450 color = getPixelColor(device, 568, 298);
8451 ok(color == 0x00ffff00,
8452 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8453 color = getPixelColor(device, 572, 298);
8454 ok(color == 0x000000ff,
8455 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8456 color = getPixelColor(device, 568, 302);
8457 ok(color == 0x000000ff,
8458 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8459 color = getPixelColor(device, 572, 302);
8460 ok(color == 0x000000ff,
8461 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8463 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8465 /* This test is pointless without those two declarations: */
8466 if((!dcl_color_2) || (!dcl_ubyte_2)) {
8467 skip("color-ubyte switching test declarations aren't supported\n");
8468 goto out;
8471 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
8472 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8473 memcpy(data, quads, sizeof(quads));
8474 hr = IDirect3DVertexBuffer9_Unlock(vb);
8475 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8476 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
8477 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8478 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8479 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
8480 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8481 memcpy(data, colors, sizeof(colors));
8482 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8483 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8485 for(i = 0; i < 2; i++) {
8486 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8487 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8489 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
8490 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8491 if(i == 0) {
8492 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
8493 } else {
8494 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
8496 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8498 hr = IDirect3DDevice9_BeginScene(device);
8499 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
8500 ub_ok = FALSE;
8501 if(SUCCEEDED(hr)) {
8502 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8503 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8504 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8505 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8506 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8507 ub_ok = SUCCEEDED(hr);
8509 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
8510 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8511 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8512 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8514 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8516 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8517 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8518 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8519 ub_ok = (SUCCEEDED(hr) && ub_ok);
8521 hr = IDirect3DDevice9_EndScene(device);
8522 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
8525 if(i == 0) {
8526 color = getPixelColor(device, 480, 360);
8527 ok(color == 0x00ff0000,
8528 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
8529 color = getPixelColor(device, 160, 120);
8530 ok(color == 0x00ffffff,
8531 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8532 color = getPixelColor(device, 160, 360);
8533 ok(color == 0x000000ff || !ub_ok,
8534 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8535 color = getPixelColor(device, 480, 120);
8536 ok(color == 0x000000ff || !ub_ok,
8537 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8538 } else {
8539 color = getPixelColor(device, 480, 360);
8540 ok(color == 0x000000ff,
8541 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
8542 color = getPixelColor(device, 160, 120);
8543 ok(color == 0x00ffffff,
8544 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8545 color = getPixelColor(device, 160, 360);
8546 ok(color == 0x00ff0000 || !ub_ok,
8547 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8548 color = getPixelColor(device, 480, 120);
8549 ok(color == 0x00ff0000 || !ub_ok,
8550 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8552 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8555 IDirect3DVertexBuffer9_Release(vb2);
8556 out:
8557 IDirect3DVertexBuffer9_Release(vb);
8558 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
8559 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
8560 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
8561 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
8562 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
8563 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
8564 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
8565 refcount = IDirect3DDevice9_Release(device);
8566 ok(!refcount, "Device has %u references left.\n", refcount);
8567 done:
8568 IDirect3D9_Release(d3d);
8569 DestroyWindow(window);
8572 static void test_vshader_float16(void)
8574 IDirect3DVertexDeclaration9 *vdecl = NULL;
8575 IDirect3DVertexBuffer9 *buffer = NULL;
8576 IDirect3DVertexShader9 *shader;
8577 IDirect3DDevice9 *device;
8578 IDirect3D9 *d3d;
8579 ULONG refcount;
8580 D3DCAPS9 caps;
8581 DWORD color;
8582 HWND window;
8583 void *data;
8584 HRESULT hr;
8586 static const D3DVERTEXELEMENT9 decl_elements[] =
8588 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8589 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8590 D3DDECL_END()
8592 static const DWORD shader_code[] =
8594 0xfffe0101, /* vs_1_1 */
8595 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8596 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8597 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8598 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8599 0x0000ffff,
8601 static const struct vertex_float16color
8603 float x, y, z;
8604 DWORD c1, c2;
8606 quad[] =
8608 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
8609 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8610 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
8611 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8613 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
8614 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8615 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
8616 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8618 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
8619 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8620 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
8621 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8623 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
8624 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8625 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
8626 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8629 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8630 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8631 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8632 ok(!!d3d, "Failed to create a D3D object.\n");
8633 if (!(device = create_device(d3d, window, window, TRUE)))
8635 skip("Failed to create a D3D device, skipping tests.\n");
8636 goto done;
8639 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8640 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8641 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8643 skip("No vs_3_0 support, skipping tests.\n");
8644 IDirect3DDevice9_Release(device);
8645 goto done;
8648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
8649 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8651 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
8652 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
8653 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8654 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8655 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8656 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8658 hr = IDirect3DDevice9_BeginScene(device);
8659 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8660 if(SUCCEEDED(hr)) {
8661 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
8662 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
8664 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
8666 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8667 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
8668 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
8670 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8672 hr = IDirect3DDevice9_EndScene(device);
8673 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8675 color = getPixelColor(device, 480, 360);
8676 ok(color == 0x00ff0000,
8677 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8678 color = getPixelColor(device, 160, 120);
8679 ok(color == 0x00000000,
8680 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8681 color = getPixelColor(device, 160, 360);
8682 ok(color == 0x0000ff00,
8683 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8684 color = getPixelColor(device, 480, 120);
8685 ok(color == 0x000000ff,
8686 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8687 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
8690 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8692 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
8693 D3DPOOL_MANAGED, &buffer, NULL);
8694 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
8695 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
8696 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
8697 memcpy(data, quad, sizeof(quad));
8698 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8699 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
8700 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
8701 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8703 hr = IDirect3DDevice9_BeginScene(device);
8704 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8705 if(SUCCEEDED(hr)) {
8706 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8707 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8708 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8709 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8710 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8711 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8712 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8715 hr = IDirect3DDevice9_EndScene(device);
8716 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8719 color = getPixelColor(device, 480, 360);
8720 ok(color == 0x00ff0000,
8721 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8722 color = getPixelColor(device, 160, 120);
8723 ok(color == 0x00000000,
8724 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8725 color = getPixelColor(device, 160, 360);
8726 ok(color == 0x0000ff00,
8727 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8728 color = getPixelColor(device, 480, 120);
8729 ok(color == 0x000000ff,
8730 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8731 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8733 IDirect3DVertexDeclaration9_Release(vdecl);
8734 IDirect3DVertexShader9_Release(shader);
8735 IDirect3DVertexBuffer9_Release(buffer);
8736 refcount = IDirect3DDevice9_Release(device);
8737 ok(!refcount, "Device has %u references left.\n", refcount);
8738 done:
8739 IDirect3D9_Release(d3d);
8740 DestroyWindow(window);
8743 static void conditional_np2_repeat_test(void)
8745 IDirect3DTexture9 *texture;
8746 IDirect3DDevice9 *device;
8747 D3DLOCKED_RECT rect;
8748 unsigned int x, y;
8749 DWORD *dst, color;
8750 IDirect3D9 *d3d;
8751 ULONG refcount;
8752 D3DCAPS9 caps;
8753 HWND window;
8754 HRESULT hr;
8756 static const float quad[] =
8758 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
8759 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
8760 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
8761 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
8764 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8765 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8766 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8767 ok(!!d3d, "Failed to create a D3D object.\n");
8768 if (!(device = create_device(d3d, window, window, TRUE)))
8770 skip("Failed to create a D3D device, skipping tests.\n");
8771 goto done;
8774 memset(&caps, 0, sizeof(caps));
8775 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8776 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8777 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8779 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
8780 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
8781 "Card has conditional NP2 support without power of two restriction set\n");
8783 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8785 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8786 IDirect3DDevice9_Release(device);
8787 goto done;
8789 else
8791 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8792 IDirect3DDevice9_Release(device);
8793 goto done;
8796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
8797 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8799 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8800 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8802 memset(&rect, 0, sizeof(rect));
8803 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8804 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8805 for(y = 0; y < 10; y++) {
8806 for(x = 0; x < 10; x++) {
8807 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8808 if(x == 0 || x == 9 || y == 0 || y == 9) {
8809 *dst = 0x00ff0000;
8810 } else {
8811 *dst = 0x000000ff;
8815 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8816 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8818 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8819 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8821 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8822 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8823 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8824 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8825 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8826 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8827 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8829 hr = IDirect3DDevice9_BeginScene(device);
8830 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8831 if(SUCCEEDED(hr)) {
8832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8833 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8835 hr = IDirect3DDevice9_EndScene(device);
8836 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8839 color = getPixelColor(device, 1, 1);
8840 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8841 color = getPixelColor(device, 639, 479);
8842 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8844 color = getPixelColor(device, 135, 101);
8845 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8846 color = getPixelColor(device, 140, 101);
8847 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8848 color = getPixelColor(device, 135, 105);
8849 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8850 color = getPixelColor(device, 140, 105);
8851 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8853 color = getPixelColor(device, 135, 376);
8854 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8855 color = getPixelColor(device, 140, 376);
8856 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8857 color = getPixelColor(device, 135, 379);
8858 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8859 color = getPixelColor(device, 140, 379);
8860 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8862 color = getPixelColor(device, 500, 101);
8863 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8864 color = getPixelColor(device, 504, 101);
8865 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8866 color = getPixelColor(device, 500, 105);
8867 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8868 color = getPixelColor(device, 504, 105);
8869 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8871 color = getPixelColor(device, 500, 376);
8872 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8873 color = getPixelColor(device, 504, 376);
8874 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8875 color = getPixelColor(device, 500, 380);
8876 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8877 color = getPixelColor(device, 504, 380);
8878 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8880 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8882 IDirect3DTexture9_Release(texture);
8883 refcount = IDirect3DDevice9_Release(device);
8884 ok(!refcount, "Device has %u references left.\n", refcount);
8885 done:
8886 IDirect3D9_Release(d3d);
8887 DestroyWindow(window);
8890 static void vface_register_test(void)
8892 IDirect3DSurface9 *surface, *backbuffer;
8893 IDirect3DVertexShader9 *vshader;
8894 IDirect3DPixelShader9 *shader;
8895 IDirect3DTexture9 *texture;
8896 IDirect3DDevice9 *device;
8897 IDirect3D9 *d3d;
8898 ULONG refcount;
8899 D3DCAPS9 caps;
8900 DWORD color;
8901 HWND window;
8902 HRESULT hr;
8904 static const DWORD shader_code[] =
8906 0xffff0300, /* ps_3_0 */
8907 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8908 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8909 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8910 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8911 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8912 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8913 0x0000ffff /* END */
8915 static const DWORD vshader_code[] =
8917 0xfffe0300, /* vs_3_0 */
8918 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8919 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8920 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8921 0x0000ffff /* end */
8923 static const float quad[] =
8925 -1.0f, -1.0f, 0.1f,
8926 1.0f, -1.0f, 0.1f,
8927 -1.0f, 0.0f, 0.1f,
8929 1.0f, -1.0f, 0.1f,
8930 1.0f, 0.0f, 0.1f,
8931 -1.0f, 0.0f, 0.1f,
8933 -1.0f, 0.0f, 0.1f,
8934 -1.0f, 1.0f, 0.1f,
8935 1.0f, 0.0f, 0.1f,
8937 1.0f, 0.0f, 0.1f,
8938 -1.0f, 1.0f, 0.1f,
8939 1.0f, 1.0f, 0.1f,
8941 static const float blit[] =
8943 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
8944 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
8945 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
8946 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
8949 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8950 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8951 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8952 ok(!!d3d, "Failed to create a D3D object.\n");
8953 if (!(device = create_device(d3d, window, window, TRUE)))
8955 skip("Failed to create a D3D device, skipping tests.\n");
8956 goto done;
8959 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8960 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8961 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8963 skip("No shader model 3 support, skipping tests.\n");
8964 IDirect3DDevice9_Release(device);
8965 goto done;
8968 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8969 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8970 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8971 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8972 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8973 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8974 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8975 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8977 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
8978 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8979 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8980 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8981 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8982 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8983 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8984 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8985 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8987 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8988 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8990 hr = IDirect3DDevice9_BeginScene(device);
8991 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8992 if(SUCCEEDED(hr)) {
8993 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8994 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8995 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8996 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8997 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8999 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9000 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9001 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9003 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9005 /* Blit the texture onto the back buffer to make it visible */
9006 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9007 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
9008 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9009 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9010 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9011 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9012 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9013 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
9014 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9015 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
9016 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9017 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9019 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9020 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9022 hr = IDirect3DDevice9_EndScene(device);
9023 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9026 color = getPixelColor(device, 160, 360);
9027 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9028 color = getPixelColor(device, 160, 120);
9029 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9030 color = getPixelColor(device, 480, 360);
9031 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9032 color = getPixelColor(device, 480, 120);
9033 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9034 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9035 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9037 IDirect3DPixelShader9_Release(shader);
9038 IDirect3DVertexShader9_Release(vshader);
9039 IDirect3DSurface9_Release(surface);
9040 IDirect3DSurface9_Release(backbuffer);
9041 IDirect3DTexture9_Release(texture);
9042 refcount = IDirect3DDevice9_Release(device);
9043 ok(!refcount, "Device has %u references left.\n", refcount);
9044 done:
9045 IDirect3D9_Release(d3d);
9046 DestroyWindow(window);
9049 static void fixed_function_bumpmap_test(void)
9051 IDirect3DVertexDeclaration9 *vertex_declaration;
9052 IDirect3DTexture9 *texture, *tex1, *tex2;
9053 D3DLOCKED_RECT locked_rect;
9054 IDirect3DDevice9 *device;
9055 BOOL L6V5U5_supported;
9056 float scale, offset;
9057 IDirect3D9 *d3d;
9058 unsigned int i;
9059 D3DCOLOR color;
9060 ULONG refcount;
9061 D3DCAPS9 caps;
9062 HWND window;
9063 HRESULT hr;
9065 static const float quad[][7] =
9067 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9068 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9069 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9070 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9072 static const D3DVERTEXELEMENT9 decl_elements[] =
9074 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9075 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9076 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9077 D3DDECL_END()
9079 /* use asymmetric matrix to test loading */
9080 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9082 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9083 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9084 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9085 ok(!!d3d, "Failed to create a D3D object.\n");
9086 if (!(device = create_device(d3d, window, window, TRUE)))
9088 skip("Failed to create a D3D device, skipping tests.\n");
9089 goto done;
9092 memset(&caps, 0, sizeof(caps));
9093 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9094 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9095 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9097 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9098 IDirect3DDevice9_Release(device);
9099 goto done;
9102 /* This check is disabled, some Windows drivers do not handle
9103 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9104 * supported, but after that bump mapping works properly. So just test if
9105 * the format is generally supported, and check the BUMPENVMAP flag. */
9106 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9107 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9108 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9109 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9111 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9112 IDirect3DDevice9_Release(device);
9113 return;
9116 /* Generate the textures */
9117 generate_bumpmap_textures(device);
9119 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9120 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9121 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9122 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9123 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9124 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9125 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9126 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9128 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9129 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9130 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9131 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9132 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9133 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9135 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9136 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9137 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9138 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9139 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9140 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9142 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9143 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9145 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9146 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9148 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9149 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9151 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9152 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9153 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9154 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9156 hr = IDirect3DDevice9_BeginScene(device);
9157 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9160 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9162 hr = IDirect3DDevice9_EndScene(device);
9163 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9165 color = getPixelColor(device, 240, 60);
9166 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9167 color = getPixelColor(device, 400, 60);
9168 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9169 color = getPixelColor(device, 80, 180);
9170 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9171 color = getPixelColor(device, 560, 180);
9172 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9173 color = getPixelColor(device, 80, 300);
9174 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9175 color = getPixelColor(device, 560, 300);
9176 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9177 color = getPixelColor(device, 240, 420);
9178 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9179 color = getPixelColor(device, 400, 420);
9180 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9182 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9184 for(i = 0; i < 2; i++) {
9185 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9186 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9187 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9188 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9189 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9190 IDirect3DTexture9_Release(texture); /* To destroy it */
9193 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9195 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9196 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9197 IDirect3DDevice9_Release(device);
9198 goto done;
9201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9202 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9203 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9204 * would only make this test more complicated
9206 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9207 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9208 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9209 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9211 memset(&locked_rect, 0, sizeof(locked_rect));
9212 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9213 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9214 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9215 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9216 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9218 memset(&locked_rect, 0, sizeof(locked_rect));
9219 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9220 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9221 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9222 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9223 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9225 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9226 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9227 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9228 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9230 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9231 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9232 scale = 2.0;
9233 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9234 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9235 offset = 0.1;
9236 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9237 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9239 hr = IDirect3DDevice9_BeginScene(device);
9240 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9241 if(SUCCEEDED(hr)) {
9242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9243 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9244 hr = IDirect3DDevice9_EndScene(device);
9245 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9248 color = getPixelColor(device, 320, 240);
9249 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9250 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9251 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9253 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9254 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9255 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9257 /* Check a result scale factor > 1.0 */
9258 scale = 10;
9259 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9260 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9261 offset = 10;
9262 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9263 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9265 hr = IDirect3DDevice9_BeginScene(device);
9266 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9267 if(SUCCEEDED(hr)) {
9268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9269 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9270 hr = IDirect3DDevice9_EndScene(device);
9271 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9273 color = getPixelColor(device, 320, 240);
9274 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9276 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9278 /* Check clamping in the scale factor calculation */
9279 scale = 1000;
9280 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9281 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9282 offset = -1;
9283 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9284 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9286 hr = IDirect3DDevice9_BeginScene(device);
9287 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9288 if(SUCCEEDED(hr)) {
9289 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9290 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9291 hr = IDirect3DDevice9_EndScene(device);
9292 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9294 color = getPixelColor(device, 320, 240);
9295 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9299 IDirect3DTexture9_Release(tex1);
9300 IDirect3DTexture9_Release(tex2);
9301 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9302 refcount = IDirect3DDevice9_Release(device);
9303 ok(!refcount, "Device has %u references left.\n", refcount);
9304 done:
9305 IDirect3D9_Release(d3d);
9306 DestroyWindow(window);
9309 static void stencil_cull_test(void)
9311 IDirect3DDevice9 *device;
9312 IDirect3D9 *d3d;
9313 ULONG refcount;
9314 D3DCAPS9 caps;
9315 HWND window;
9316 HRESULT hr;
9317 static const float quad1[] =
9319 -1.0, -1.0, 0.1,
9320 0.0, -1.0, 0.1,
9321 -1.0, 0.0, 0.1,
9322 0.0, 0.0, 0.1,
9324 static const float quad2[] =
9326 0.0, -1.0, 0.1,
9327 1.0, -1.0, 0.1,
9328 0.0, 0.0, 0.1,
9329 1.0, 0.0, 0.1,
9331 static const float quad3[] =
9333 0.0, 0.0, 0.1,
9334 1.0, 0.0, 0.1,
9335 0.0, 1.0, 0.1,
9336 1.0, 1.0, 0.1,
9338 static const float quad4[] =
9340 -1.0, 0.0, 0.1,
9341 0.0, 0.0, 0.1,
9342 -1.0, 1.0, 0.1,
9343 0.0, 1.0, 0.1,
9345 struct vertex painter[] =
9347 {-1.0, -1.0, 0.0, 0x00000000},
9348 { 1.0, -1.0, 0.0, 0x00000000},
9349 {-1.0, 1.0, 0.0, 0x00000000},
9350 { 1.0, 1.0, 0.0, 0x00000000},
9352 static const WORD indices_cw[] = {0, 1, 3};
9353 static const WORD indices_ccw[] = {0, 2, 3};
9354 unsigned int i;
9355 DWORD color;
9357 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9358 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9359 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9360 ok(!!d3d, "Failed to create a D3D object.\n");
9361 if (!(device = create_device(d3d, window, window, TRUE)))
9363 skip("Cannot create a device with a D24S8 stencil buffer.\n");
9364 DestroyWindow(window);
9365 IDirect3D9_Release(d3d);
9366 return;
9368 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9369 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9370 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
9372 skip("No two sided stencil support\n");
9373 goto cleanup;
9376 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
9377 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9378 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9379 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
9381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9382 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
9383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9384 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
9385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
9386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
9388 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
9390 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
9392 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
9395 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
9397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
9399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
9402 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9404 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9406 /* First pass: Fill the stencil buffer with some values... */
9407 hr = IDirect3DDevice9_BeginScene(device);
9408 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
9409 if(SUCCEEDED(hr))
9411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9413 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9414 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9415 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9416 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9417 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9418 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
9421 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9423 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9424 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9425 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9426 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9427 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9428 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9429 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9432 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9433 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9434 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9435 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9436 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9437 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9438 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
9441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9442 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9443 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9444 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9445 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9446 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9447 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9449 hr = IDirect3DDevice9_EndScene(device);
9450 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
9453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
9454 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
9456 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
9458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9460 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9466 /* 2nd pass: Make the stencil values visible */
9467 hr = IDirect3DDevice9_BeginScene(device);
9468 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
9469 if(SUCCEEDED(hr))
9471 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9472 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9473 for (i = 0; i < 16; ++i)
9475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
9476 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9478 painter[0].diffuse = (i * 16); /* Creates shades of blue */
9479 painter[1].diffuse = (i * 16);
9480 painter[2].diffuse = (i * 16);
9481 painter[3].diffuse = (i * 16);
9482 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
9483 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
9485 hr = IDirect3DDevice9_EndScene(device);
9486 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
9489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9490 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9492 color = getPixelColor(device, 160, 420);
9493 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
9494 color = getPixelColor(device, 160, 300);
9495 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9497 color = getPixelColor(device, 480, 420);
9498 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
9499 color = getPixelColor(device, 480, 300);
9500 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
9502 color = getPixelColor(device, 160, 180);
9503 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
9504 color = getPixelColor(device, 160, 60);
9505 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
9507 color = getPixelColor(device, 480, 180);
9508 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
9509 color = getPixelColor(device, 480, 60);
9510 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9512 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9513 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9515 cleanup:
9516 refcount = IDirect3DDevice9_Release(device);
9517 ok(!refcount, "Device has %u references left.\n", refcount);
9518 IDirect3D9_Release(d3d);
9519 DestroyWindow(window);
9522 static void vpos_register_test(void)
9524 IDirect3DSurface9 *surface = NULL, *backbuffer;
9525 IDirect3DPixelShader9 *shader, *shader_frac;
9526 IDirect3DVertexShader9 *vshader;
9527 IDirect3DDevice9 *device;
9528 D3DLOCKED_RECT lr;
9529 IDirect3D9 *d3d;
9530 ULONG refcount;
9531 D3DCAPS9 caps;
9532 DWORD color;
9533 HWND window;
9534 HRESULT hr;
9535 DWORD *pos;
9537 static const DWORD shader_code[] =
9539 0xffff0300, /* ps_3_0 */
9540 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9541 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
9542 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
9543 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
9544 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
9545 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
9546 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
9547 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
9548 0x0000ffff /* end */
9550 static const DWORD shader_frac_code[] =
9552 0xffff0300, /* ps_3_0 */
9553 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
9554 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9555 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
9556 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
9557 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9558 0x0000ffff /* end */
9560 static const DWORD vshader_code[] =
9562 0xfffe0300, /* vs_3_0 */
9563 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9564 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9565 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9566 0x0000ffff /* end */
9568 static const float quad[] =
9570 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9571 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9572 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9573 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9575 float constant[4] = {1.0, 0.0, 320, 240};
9577 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9578 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9579 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9580 ok(!!d3d, "Failed to create a D3D object.\n");
9581 if (!(device = create_device(d3d, window, window, TRUE)))
9583 skip("Failed to create a D3D device, skipping tests.\n");
9584 goto done;
9587 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9588 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9589 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9591 skip("No shader model 3 support, skipping tests.\n");
9592 IDirect3DDevice9_Release(device);
9593 goto done;
9596 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9597 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9598 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9599 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9600 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9601 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9602 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
9603 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9604 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9605 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9606 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9607 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9608 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9609 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9610 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9611 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9613 hr = IDirect3DDevice9_BeginScene(device);
9614 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9615 if(SUCCEEDED(hr)) {
9616 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9617 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
9618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9619 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9620 hr = IDirect3DDevice9_EndScene(device);
9621 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9624 /* This has to be pixel exact */
9625 color = getPixelColor(device, 319, 239);
9626 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
9627 color = getPixelColor(device, 320, 239);
9628 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
9629 color = getPixelColor(device, 319, 240);
9630 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
9631 color = getPixelColor(device, 320, 240);
9632 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
9633 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9635 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
9636 &surface, NULL);
9637 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
9638 hr = IDirect3DDevice9_BeginScene(device);
9639 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9640 if(SUCCEEDED(hr)) {
9641 constant[2] = 16; constant[3] = 16;
9642 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9643 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
9644 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9647 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9648 hr = IDirect3DDevice9_EndScene(device);
9649 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9651 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9652 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9654 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9655 color = *pos & 0x00ffffff;
9656 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
9657 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
9658 color = *pos & 0x00ffffff;
9659 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
9660 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
9661 color = *pos & 0x00ffffff;
9662 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
9663 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
9664 color = *pos & 0x00ffffff;
9665 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
9667 hr = IDirect3DSurface9_UnlockRect(surface);
9668 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9670 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
9671 * have full control over the multisampling setting inside this test
9673 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
9674 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9675 hr = IDirect3DDevice9_BeginScene(device);
9676 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9677 if(SUCCEEDED(hr)) {
9678 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9679 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9681 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9682 hr = IDirect3DDevice9_EndScene(device);
9683 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9685 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9686 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9688 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9689 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9691 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9692 color = *pos & 0x00ffffff;
9693 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
9695 hr = IDirect3DSurface9_UnlockRect(surface);
9696 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9698 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9700 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9701 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9702 IDirect3DPixelShader9_Release(shader);
9703 IDirect3DPixelShader9_Release(shader_frac);
9704 IDirect3DVertexShader9_Release(vshader);
9705 if(surface) IDirect3DSurface9_Release(surface);
9706 IDirect3DSurface9_Release(backbuffer);
9707 refcount = IDirect3DDevice9_Release(device);
9708 ok(!refcount, "Device has %u references left.\n", refcount);
9709 done:
9710 IDirect3D9_Release(d3d);
9711 DestroyWindow(window);
9714 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
9716 D3DCOLOR color;
9718 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
9719 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9720 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9721 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9722 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9724 ++r;
9725 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
9726 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9727 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9728 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9729 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9731 return TRUE;
9734 static void pointsize_test(void)
9736 float ptsize, ptsizemax_orig, ptsizemin_orig;
9737 IDirect3DSurface9 *rt, *backbuffer;
9738 IDirect3DTexture9 *tex1, *tex2;
9739 IDirect3DDevice9 *device;
9740 D3DLOCKED_RECT lr;
9741 IDirect3D9 *d3d;
9742 D3DCOLOR color;
9743 ULONG refcount;
9744 D3DCAPS9 caps;
9745 HWND window;
9746 HRESULT hr;
9748 static const RECT rect = {0, 0, 128, 128};
9749 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
9750 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
9751 static const float vertices[] =
9753 64.0f, 64.0f, 0.1f,
9754 128.0f, 64.0f, 0.1f,
9755 192.0f, 64.0f, 0.1f,
9756 256.0f, 64.0f, 0.1f,
9757 320.0f, 64.0f, 0.1f,
9758 384.0f, 64.0f, 0.1f,
9759 448.0f, 64.0f, 0.1f,
9760 512.0f, 64.0f, 0.1f,
9762 /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to
9763 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
9764 D3DMATRIX matrix =
9766 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
9767 0.0f, -2.0 / 480.0f, 0.0f, 0.0f,
9768 0.0f, 0.0f, 1.0f, 0.0f,
9769 -1.0f, 1.0f, 0.0f, 1.0f,
9770 }}};
9772 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9773 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9774 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9775 ok(!!d3d, "Failed to create a D3D object.\n");
9776 if (!(device = create_device(d3d, window, window, TRUE)))
9778 skip("Failed to create a D3D device, skipping tests.\n");
9779 goto done;
9782 memset(&caps, 0, sizeof(caps));
9783 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9784 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9785 if(caps.MaxPointSize < 32.0) {
9786 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
9787 IDirect3DDevice9_Release(device);
9788 goto done;
9791 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9792 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9793 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9794 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9795 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9796 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9797 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9798 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9800 hr = IDirect3DDevice9_BeginScene(device);
9801 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9802 if (SUCCEEDED(hr))
9804 ptsize = 15.0;
9805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9806 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9808 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9810 ptsize = 31.0;
9811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9812 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
9814 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9816 ptsize = 30.75;
9817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9818 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9819 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
9820 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9822 if (caps.MaxPointSize >= 63.0)
9824 ptsize = 63.0;
9825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9826 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
9828 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9830 ptsize = 62.75;
9831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9832 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
9834 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9837 ptsize = 1.0;
9838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9839 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
9841 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9843 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
9844 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9845 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
9846 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9848 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
9849 ptsize = 15.0;
9850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9851 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9852 ptsize = 1.0;
9853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
9854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9855 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
9856 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
9859 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9861 /* pointsize < pointsize_min < pointsize_max?
9862 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
9863 ptsize = 1.0;
9864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9865 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9866 ptsize = 15.0;
9867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
9868 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
9870 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
9873 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9875 hr = IDirect3DDevice9_EndScene(device);
9876 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9879 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
9880 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
9881 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
9883 if (caps.MaxPointSize >= 63.0)
9885 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9886 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9889 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9890 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9891 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9892 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9893 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9895 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9897 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9898 * generates texture coordinates for the point(result: Yes, it does)
9900 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9901 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9902 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9904 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9905 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9907 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9908 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9909 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9910 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9911 memset(&lr, 0, sizeof(lr));
9912 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9913 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9914 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9915 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9916 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9917 memset(&lr, 0, sizeof(lr));
9918 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9919 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9920 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9921 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9922 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9923 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9925 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9926 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9927 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9928 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9929 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9930 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9931 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9932 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9933 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9934 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9935 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9936 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9939 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9940 ptsize = 32.0;
9941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9942 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9944 hr = IDirect3DDevice9_BeginScene(device);
9945 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9946 if(SUCCEEDED(hr))
9948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9949 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9950 hr = IDirect3DDevice9_EndScene(device);
9951 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9954 color = getPixelColor(device, 64-4, 64-4);
9955 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9956 color = getPixelColor(device, 64-4, 64+4);
9957 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9958 color = getPixelColor(device, 64+4, 64+4);
9959 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9960 color = getPixelColor(device, 64+4, 64-4);
9961 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9962 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9964 U(matrix).m[0][0] = 1.0f / 64.0f;
9965 U(matrix).m[1][1] = -1.0f / 64.0f;
9966 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9967 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9969 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9970 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9972 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9973 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9974 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9976 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9977 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
9979 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9981 hr = IDirect3DDevice9_BeginScene(device);
9982 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9984 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9985 hr = IDirect3DDevice9_EndScene(device);
9986 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9988 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9989 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9990 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9991 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9992 IDirect3DSurface9_Release(backbuffer);
9993 IDirect3DSurface9_Release(rt);
9995 color = getPixelColor(device, 64-4, 64-4);
9996 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9997 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9998 color = getPixelColor(device, 64+4, 64-4);
9999 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
10000 "Expected color 0x00ffff00, got 0x%08x.\n", color);
10001 color = getPixelColor(device, 64-4, 64+4);
10002 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
10003 "Expected color 0x00000000, got 0x%08x.\n", color);
10004 color = getPixelColor(device, 64+4, 64+4);
10005 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10006 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10009 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10011 IDirect3DTexture9_Release(tex1);
10012 IDirect3DTexture9_Release(tex2);
10013 refcount = IDirect3DDevice9_Release(device);
10014 ok(!refcount, "Device has %u references left.\n", refcount);
10015 done:
10016 IDirect3D9_Release(d3d);
10017 DestroyWindow(window);
10020 static void multiple_rendertargets_test(void)
10022 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
10023 IDirect3DPixelShader9 *ps1, *ps2;
10024 IDirect3DTexture9 *tex1, *tex2;
10025 IDirect3DVertexShader9 *vs;
10026 IDirect3DDevice9 *device;
10027 IDirect3D9 *d3d;
10028 ULONG refcount;
10029 D3DCAPS9 caps;
10030 DWORD color;
10031 HWND window;
10032 HRESULT hr;
10033 UINT i, j;
10035 static const DWORD vshader_code[] =
10037 0xfffe0300, /* vs_3_0 */
10038 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10039 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10040 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10041 0x0000ffff /* end */
10043 static const DWORD pshader_code1[] =
10045 0xffff0300, /* ps_3_0 */
10046 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10047 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10048 0x0000ffff /* end */
10050 static const DWORD pshader_code2[] =
10052 0xffff0300, /* ps_3_0 */
10053 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10054 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
10055 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10056 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
10057 0x0000ffff /* end */
10059 static const float quad[] =
10061 -1.0f, -1.0f, 0.1f,
10062 -1.0f, 1.0f, 0.1f,
10063 1.0f, -1.0f, 0.1f,
10064 1.0f, 1.0f, 0.1f,
10066 static const float texquad[] =
10068 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10069 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10070 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10071 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10073 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10074 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10075 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10076 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10079 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10080 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10081 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10082 ok(!!d3d, "Failed to create a D3D object.\n");
10083 if (!(device = create_device(d3d, window, window, TRUE)))
10085 skip("Failed to create a D3D device, skipping tests.\n");
10086 goto done;
10089 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10090 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10091 if (caps.NumSimultaneousRTs < 2)
10093 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
10094 IDirect3DDevice9_Release(device);
10095 goto done;
10097 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10099 skip("No shader model 3 support, skipping tests.\n");
10100 IDirect3DDevice9_Release(device);
10101 goto done;
10104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
10105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10107 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
10108 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
10109 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
10111 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10112 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
10113 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10114 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10115 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10117 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
10118 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
10119 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
10120 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10121 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
10122 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10124 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
10125 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
10126 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
10127 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10128 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
10129 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10131 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10132 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10133 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
10134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10135 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
10136 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10137 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10138 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10140 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10141 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10142 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10143 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10144 color = getPixelColorFromSurface(readback, 8, 8);
10145 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10146 "Expected color 0x000000ff, got 0x%08x.\n", color);
10147 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10148 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10149 color = getPixelColorFromSurface(readback, 8, 8);
10150 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10151 "Expected color 0x000000ff, got 0x%08x.\n", color);
10153 /* Render targets not written by the pixel shader should be unmodified. */
10154 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
10155 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10156 hr = IDirect3DDevice9_BeginScene(device);
10157 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10159 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10160 hr = IDirect3DDevice9_EndScene(device);
10161 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10162 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10163 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10164 color = getPixelColorFromSurface(readback, 8, 8);
10165 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10166 "Expected color 0xff00ff00, got 0x%08x.\n", color);
10167 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10168 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10169 for (i = 6; i < 10; ++i)
10171 for (j = 6; j < 10; ++j)
10173 color = getPixelColorFromSurface(readback, j, i);
10174 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10175 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
10179 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
10180 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10181 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10182 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10183 color = getPixelColorFromSurface(readback, 8, 8);
10184 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10185 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10186 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10187 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10188 color = getPixelColorFromSurface(readback, 8, 8);
10189 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10190 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10192 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
10193 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10195 hr = IDirect3DDevice9_BeginScene(device);
10196 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
10197 if(SUCCEEDED(hr)) {
10198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10199 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
10201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10202 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10203 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10204 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10205 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
10207 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
10208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10209 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
10210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10211 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10212 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10214 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10215 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
10216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
10217 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
10219 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
10220 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
10221 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
10222 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
10224 hr = IDirect3DDevice9_EndScene(device);
10225 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
10228 color = getPixelColor(device, 160, 240);
10229 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
10230 color = getPixelColor(device, 480, 240);
10231 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
10232 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10234 IDirect3DPixelShader9_Release(ps2);
10235 IDirect3DPixelShader9_Release(ps1);
10236 IDirect3DVertexShader9_Release(vs);
10237 IDirect3DTexture9_Release(tex1);
10238 IDirect3DTexture9_Release(tex2);
10239 IDirect3DSurface9_Release(surf1);
10240 IDirect3DSurface9_Release(surf2);
10241 IDirect3DSurface9_Release(backbuf);
10242 IDirect3DSurface9_Release(readback);
10243 refcount = IDirect3DDevice9_Release(device);
10244 ok(!refcount, "Device has %u references left.\n", refcount);
10245 done:
10246 IDirect3D9_Release(d3d);
10247 DestroyWindow(window);
10250 static void pixelshader_blending_test(void)
10252 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
10253 IDirect3DTexture9 *offscreenTexture = NULL;
10254 IDirect3DDevice9 *device;
10255 IDirect3D9 *d3d;
10256 ULONG refcount;
10257 int fmt_index;
10258 DWORD color;
10259 HWND window;
10260 HRESULT hr;
10262 static const struct
10264 const char *fmtName;
10265 D3DFORMAT textureFormat;
10266 D3DCOLOR resultColorBlending;
10267 D3DCOLOR resultColorNoBlending;
10269 test_formats[] =
10271 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
10272 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
10273 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff},
10274 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000},
10275 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
10276 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff},
10277 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000},
10279 static const float quad[][5] =
10281 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
10282 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
10283 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
10284 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
10286 /* Quad with R=0x10, G=0x20 */
10287 static const struct vertex quad1[] =
10289 {-1.0f, -1.0f, 0.1f, 0x80102000},
10290 {-1.0f, 1.0f, 0.1f, 0x80102000},
10291 { 1.0f, -1.0f, 0.1f, 0x80102000},
10292 { 1.0f, 1.0f, 0.1f, 0x80102000},
10294 /* Quad with R=0x20, G=0x10 */
10295 static const struct vertex quad2[] =
10297 {-1.0f, -1.0f, 0.1f, 0x80201000},
10298 {-1.0f, 1.0f, 0.1f, 0x80201000},
10299 { 1.0f, -1.0f, 0.1f, 0x80201000},
10300 { 1.0f, 1.0f, 0.1f, 0x80201000},
10303 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10304 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10305 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10306 ok(!!d3d, "Failed to create a D3D object.\n");
10307 if (!(device = create_device(d3d, window, window, TRUE)))
10309 skip("Failed to create a D3D device, skipping tests.\n");
10310 goto done;
10313 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10314 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
10316 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
10318 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
10320 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10321 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
10323 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
10324 continue;
10327 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10328 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
10330 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
10331 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
10332 if(!offscreenTexture) {
10333 continue;
10336 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
10337 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
10338 if(!offscreen) {
10339 continue;
10342 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10343 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
10345 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10346 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10347 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10348 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10349 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10350 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
10351 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10352 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
10353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10354 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10356 /* Below we will draw two quads with different colors and try to blend them together.
10357 * The result color is compared with the expected outcome.
10359 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
10360 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
10361 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
10362 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
10363 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
10365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
10366 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10368 /* Draw a quad using color 0x0010200 */
10369 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
10370 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
10372 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10374 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
10376 /* Draw a quad using color 0x0020100 */
10377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
10378 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10379 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
10380 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10382 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
10384 /* We don't want to blend the result on the backbuffer */
10385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10388 /* Prepare rendering the 'blended' texture quad to the backbuffer */
10389 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10390 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
10391 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
10392 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
10394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10395 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
10397 /* This time with the texture */
10398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10399 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
10401 IDirect3DDevice9_EndScene(device);
10404 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10405 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
10407 /* Compare the color of the center quad with our expectation. */
10408 color = getPixelColor(device, 320, 240);
10409 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
10410 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
10411 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
10413 else
10415 /* No pixel shader blending is supported so expect garbage. The
10416 * type of 'garbage' depends on the driver version and OS. E.g. on
10417 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
10418 * modern ones 0x002010ff which is also what NVIDIA reports. On
10419 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
10420 color = getPixelColor(device, 320, 240);
10421 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
10422 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
10423 test_formats[fmt_index].fmtName, color);
10425 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10427 IDirect3DDevice9_SetTexture(device, 0, NULL);
10428 if(offscreenTexture) {
10429 IDirect3DTexture9_Release(offscreenTexture);
10431 if(offscreen) {
10432 IDirect3DSurface9_Release(offscreen);
10436 IDirect3DSurface9_Release(backbuffer);
10437 refcount = IDirect3DDevice9_Release(device);
10438 ok(!refcount, "Device has %u references left.\n", refcount);
10439 done:
10440 IDirect3D9_Release(d3d);
10441 DestroyWindow(window);
10444 static void tssargtemp_test(void)
10446 IDirect3DDevice9 *device;
10447 IDirect3D9 *d3d;
10448 D3DCOLOR color;
10449 ULONG refcount;
10450 D3DCAPS9 caps;
10451 HWND window;
10452 HRESULT hr;
10454 static const struct vertex quad[] =
10456 {-1.0f, -1.0f, 0.1f, 0x00ff0000},
10457 {-1.0f, 1.0f, 0.1f, 0x00ff0000},
10458 { 1.0f, -1.0f, 0.1f, 0x00ff0000},
10459 { 1.0f, 1.0f, 0.1f, 0x00ff0000},
10462 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10463 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10464 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10465 ok(!!d3d, "Failed to create a D3D object.\n");
10466 if (!(device = create_device(d3d, window, window, TRUE)))
10468 skip("Failed to create a D3D device, skipping tests.\n");
10469 goto done;
10472 memset(&caps, 0, sizeof(caps));
10473 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10474 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
10475 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
10476 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
10477 IDirect3DDevice9_Release(device);
10478 goto done;
10481 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
10482 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10484 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10485 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10486 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10487 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10489 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10490 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10491 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
10492 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10493 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
10494 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10496 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
10497 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10498 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
10499 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10500 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
10501 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10503 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
10504 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
10507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10509 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10510 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10511 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10513 hr = IDirect3DDevice9_BeginScene(device);
10514 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
10515 if(SUCCEEDED(hr)) {
10516 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10517 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
10518 hr = IDirect3DDevice9_EndScene(device);
10519 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
10521 color = getPixelColor(device, 320, 240);
10522 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
10523 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10525 refcount = IDirect3DDevice9_Release(device);
10526 ok(!refcount, "Device has %u references left.\n", refcount);
10527 done:
10528 IDirect3D9_Release(d3d);
10529 DestroyWindow(window);
10532 /* Drawing Indexed Geometry with instances*/
10533 static void stream_test(void)
10535 IDirect3DVertexDeclaration9 *pDecl = NULL;
10536 IDirect3DVertexShader9 *shader = NULL;
10537 IDirect3DVertexBuffer9 *vb3 = NULL;
10538 IDirect3DVertexBuffer9 *vb2 = NULL;
10539 IDirect3DVertexBuffer9 *vb = NULL;
10540 IDirect3DIndexBuffer9 *ib = NULL;
10541 IDirect3DDevice9 *device;
10542 IDirect3D9 *d3d;
10543 ULONG refcount;
10544 D3DCAPS9 caps;
10545 DWORD color;
10546 HWND window;
10547 unsigned i;
10548 HRESULT hr;
10549 BYTE *data;
10550 DWORD ind;
10552 static const struct testdata
10554 DWORD idxVertex; /* number of instances in the first stream */
10555 DWORD idxColor; /* number of instances in the second stream */
10556 DWORD idxInstance; /* should be 1 ?? */
10557 DWORD color1; /* color 1 instance */
10558 DWORD color2; /* color 2 instance */
10559 DWORD color3; /* color 3 instance */
10560 DWORD color4; /* color 4 instance */
10561 WORD strVertex; /* specify which stream to use 0-2*/
10562 WORD strColor;
10563 WORD strInstance;
10565 testcases[]=
10567 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
10568 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
10569 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
10570 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
10571 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
10572 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
10573 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
10574 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
10575 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
10576 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
10577 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
10578 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
10579 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
10580 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
10581 #if 0
10582 /* This draws one instance on some machines, no instance on others. */
10583 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
10584 /* This case is handled in a stand alone test,
10585 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
10586 * return D3DERR_INVALIDCALL. */
10587 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
10588 #endif
10590 static const DWORD shader_code[] =
10592 0xfffe0101, /* vs_1_1 */
10593 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10594 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
10595 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
10596 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10597 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
10598 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
10599 0x0000ffff
10601 static const float quad[][3] =
10603 {-0.5f, -0.5f, 1.1f}, /*0 */
10604 {-0.5f, 0.5f, 1.1f}, /*1 */
10605 { 0.5f, -0.5f, 1.1f}, /*2 */
10606 { 0.5f, 0.5f, 1.1f}, /*3 */
10608 static const float vertcolor[][4] =
10610 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
10611 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
10612 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
10613 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
10615 /* 4 position for 4 instances */
10616 static const float instancepos[][3] =
10618 {-0.6f,-0.6f, 0.0f},
10619 { 0.6f,-0.6f, 0.0f},
10620 { 0.6f, 0.6f, 0.0f},
10621 {-0.6f, 0.6f, 0.0f},
10623 static const short indices[] = {0, 1, 2, 2, 1, 3};
10624 D3DVERTEXELEMENT9 decl[] =
10626 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10627 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10628 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10629 D3DDECL_END()
10632 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10633 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10634 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10635 ok(!!d3d, "Failed to create a D3D object.\n");
10636 if (!(device = create_device(d3d, window, window, TRUE)))
10638 skip("Failed to create a D3D device, skipping tests.\n");
10639 goto done;
10642 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10643 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10644 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10646 skip("No vs_3_0 support, skipping tests.\n");
10647 IDirect3DDevice9_Release(device);
10648 goto done;
10651 /* set the default value because it isn't done in wine? */
10652 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10653 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10655 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
10656 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
10657 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10659 /* check wrong cases */
10660 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
10661 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10662 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10663 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10664 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
10665 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10666 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10667 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10668 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
10669 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10670 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10671 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10672 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
10673 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10674 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10675 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10676 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
10677 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10678 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10679 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10681 /* set the default value back */
10682 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10683 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10685 /* create all VertexBuffers*/
10686 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
10687 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10688 if(!vb) {
10689 skip("Failed to create a vertex buffer\n");
10690 IDirect3DDevice9_Release(device);
10691 goto done;
10693 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
10694 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10695 if(!vb2) {
10696 skip("Failed to create a vertex buffer\n");
10697 goto out;
10699 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
10700 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10701 if(!vb3) {
10702 skip("Failed to create a vertex buffer\n");
10703 goto out;
10706 /* create IndexBuffer*/
10707 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
10708 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
10709 if(!ib) {
10710 skip("Failed to create an index buffer\n");
10711 goto out;
10714 /* copy all Buffers (Vertex + Index)*/
10715 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
10716 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10717 memcpy(data, quad, sizeof(quad));
10718 hr = IDirect3DVertexBuffer9_Unlock(vb);
10719 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10720 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
10721 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10722 memcpy(data, vertcolor, sizeof(vertcolor));
10723 hr = IDirect3DVertexBuffer9_Unlock(vb2);
10724 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10725 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
10726 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10727 memcpy(data, instancepos, sizeof(instancepos));
10728 hr = IDirect3DVertexBuffer9_Unlock(vb3);
10729 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10730 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
10731 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
10732 memcpy(data, indices, sizeof(indices));
10733 hr = IDirect3DIndexBuffer9_Unlock(ib);
10734 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
10736 /* create VertexShader */
10737 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10738 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10739 if(!shader) {
10740 skip("Failed to create a vetex shader\n");
10741 goto out;
10744 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10745 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10747 hr = IDirect3DDevice9_SetIndices(device, ib);
10748 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
10750 /* run all tests */
10751 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
10753 struct testdata act = testcases[i];
10754 decl[0].Stream = act.strVertex;
10755 decl[1].Stream = act.strColor;
10756 decl[2].Stream = act.strInstance;
10757 /* create VertexDeclarations */
10758 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
10759 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
10761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10762 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
10764 hr = IDirect3DDevice9_BeginScene(device);
10765 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
10766 if(SUCCEEDED(hr))
10768 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
10769 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
10771 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
10772 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10773 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
10774 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10776 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
10777 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10778 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
10779 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10781 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
10782 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10783 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
10784 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10786 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
10787 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
10788 hr = IDirect3DDevice9_EndScene(device);
10789 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
10791 /* set all StreamSource && StreamSourceFreq back to default */
10792 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
10793 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10794 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
10795 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10796 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
10797 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10798 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
10799 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10800 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
10801 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10802 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
10803 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10806 hr = IDirect3DVertexDeclaration9_Release(pDecl);
10807 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
10809 color = getPixelColor(device, 160, 360);
10810 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
10811 color = getPixelColor(device, 480, 360);
10812 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
10813 color = getPixelColor(device, 480, 120);
10814 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
10815 color = getPixelColor(device, 160, 120);
10816 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
10818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10819 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
10822 out:
10823 if(vb) IDirect3DVertexBuffer9_Release(vb);
10824 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
10825 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
10826 if(ib)IDirect3DIndexBuffer9_Release(ib);
10827 if(shader)IDirect3DVertexShader9_Release(shader);
10828 refcount = IDirect3DDevice9_Release(device);
10829 ok(!refcount, "Device has %u references left.\n", refcount);
10830 done:
10831 IDirect3D9_Release(d3d);
10832 DestroyWindow(window);
10835 static void np2_stretch_rect_test(void)
10837 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
10838 IDirect3DTexture9 *dsttex = NULL;
10839 IDirect3DDevice9 *device;
10840 IDirect3D9 *d3d;
10841 D3DCOLOR color;
10842 ULONG refcount;
10843 HWND window;
10844 HRESULT hr;
10846 static const D3DRECT r1 = {0, 0, 50, 50 };
10847 static const D3DRECT r2 = {50, 0, 100, 50 };
10848 static const D3DRECT r3 = {50, 50, 100, 100};
10849 static const D3DRECT r4 = {0, 50, 50, 100};
10850 static const float quad[] =
10852 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10853 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10854 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10855 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10858 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10859 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10860 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10861 ok(!!d3d, "Failed to create a D3D object.\n");
10862 if (!(device = create_device(d3d, window, window, TRUE)))
10864 skip("Failed to create a D3D device, skipping tests.\n");
10865 goto done;
10868 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10869 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
10871 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
10872 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
10873 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
10874 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
10876 if(!src || !dsttex) {
10877 skip("One or more test resources could not be created\n");
10878 goto cleanup;
10881 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
10882 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
10884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10885 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10887 /* Clear the StretchRect destination for debugging */
10888 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
10889 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10890 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
10891 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10893 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
10894 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10896 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10898 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
10899 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10900 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10901 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10902 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
10903 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10905 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
10906 * the target -> texture GL blit path
10908 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
10909 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
10910 IDirect3DSurface9_Release(dst);
10912 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10913 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10915 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
10916 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10917 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10918 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10919 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10920 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10922 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10924 hr = IDirect3DDevice9_BeginScene(device);
10925 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
10926 if(SUCCEEDED(hr)) {
10927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10928 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
10929 hr = IDirect3DDevice9_EndScene(device);
10930 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
10933 color = getPixelColor(device, 160, 360);
10934 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
10935 color = getPixelColor(device, 480, 360);
10936 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
10937 color = getPixelColor(device, 480, 120);
10938 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
10939 color = getPixelColor(device, 160, 120);
10940 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
10941 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10942 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10944 cleanup:
10945 if(src) IDirect3DSurface9_Release(src);
10946 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
10947 if(dsttex) IDirect3DTexture9_Release(dsttex);
10948 refcount = IDirect3DDevice9_Release(device);
10949 ok(!refcount, "Device has %u references left.\n", refcount);
10950 done:
10951 IDirect3D9_Release(d3d);
10952 DestroyWindow(window);
10955 static void texop_test(void)
10957 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10958 IDirect3DTexture9 *texture = NULL;
10959 D3DLOCKED_RECT locked_rect;
10960 IDirect3DDevice9 *device;
10961 IDirect3D9 *d3d;
10962 D3DCOLOR color;
10963 ULONG refcount;
10964 D3DCAPS9 caps;
10965 HWND window;
10966 HRESULT hr;
10967 unsigned i;
10969 static const struct {
10970 float x, y, z;
10971 float s, t;
10972 D3DCOLOR diffuse;
10973 } quad[] = {
10974 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10975 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10976 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10977 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10980 static const D3DVERTEXELEMENT9 decl_elements[] = {
10981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10982 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10983 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10984 D3DDECL_END()
10987 static const struct {
10988 D3DTEXTUREOP op;
10989 const char *name;
10990 DWORD caps_flag;
10991 D3DCOLOR result;
10992 } test_data[] = {
10993 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10994 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10995 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10996 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10997 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10998 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10999 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
11000 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11001 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11002 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11003 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11004 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
11005 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
11006 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11007 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11008 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
11009 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
11010 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11011 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
11012 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
11013 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
11014 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
11015 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
11018 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11019 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11020 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11021 ok(!!d3d, "Failed to create a D3D object.\n");
11022 if (!(device = create_device(d3d, window, window, TRUE)))
11024 skip("Failed to create a D3D device, skipping tests.\n");
11025 goto done;
11028 memset(&caps, 0, sizeof(caps));
11029 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11030 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11032 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11033 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
11034 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
11035 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
11037 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11038 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11039 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11040 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11041 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
11042 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11043 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11044 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11045 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
11048 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11049 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11050 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11051 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11052 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11054 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
11055 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11058 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
11060 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
11062 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11065 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11067 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
11069 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
11071 skip("tex operation %s not supported\n", test_data[i].name);
11072 continue;
11075 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
11076 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
11078 hr = IDirect3DDevice9_BeginScene(device);
11079 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11081 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11082 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11084 hr = IDirect3DDevice9_EndScene(device);
11085 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11087 color = getPixelColor(device, 320, 240);
11088 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
11089 test_data[i].name, color, test_data[i].result);
11091 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11092 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11095 IDirect3DTexture9_Release(texture);
11096 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11097 refcount = IDirect3DDevice9_Release(device);
11098 ok(!refcount, "Device has %u references left.\n", refcount);
11099 done:
11100 IDirect3D9_Release(d3d);
11101 DestroyWindow(window);
11104 static void yuv_color_test(void)
11106 HRESULT hr;
11107 IDirect3DSurface9 *surface, *target;
11108 unsigned int i;
11109 D3DLOCKED_RECT lr;
11110 IDirect3D9 *d3d;
11111 D3DCOLOR color;
11112 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
11113 IDirect3DDevice9 *device;
11114 D3DSURFACE_DESC desc;
11115 ULONG refcount;
11116 HWND window;
11118 static const struct
11120 DWORD in;
11121 D3DFORMAT format;
11122 const char *fmt_string;
11123 D3DCOLOR left, right;
11125 test_data[] =
11127 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
11128 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
11129 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
11130 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
11131 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
11132 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
11133 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
11134 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
11135 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
11136 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
11137 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
11138 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
11139 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
11140 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
11141 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
11142 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
11143 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
11144 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
11146 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
11147 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
11148 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
11149 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
11150 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
11151 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
11152 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
11153 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
11154 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
11155 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
11156 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
11157 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
11158 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
11159 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
11160 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
11161 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
11162 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
11163 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
11166 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11167 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11168 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11169 ok(!!d3d, "Failed to create a D3D object.\n");
11170 if (!(device = create_device(d3d, window, window, TRUE)))
11172 skip("Failed to create a D3D device, skipping tests.\n");
11173 goto done;
11176 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11177 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
11178 hr = IDirect3DSurface9_GetDesc(target, &desc);
11179 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11181 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11183 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
11184 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
11185 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11186 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
11188 if (skip_once != test_data[i].format)
11190 skip("%s is not supported.\n", test_data[i].fmt_string);
11191 skip_once = test_data[i].format;
11193 continue;
11195 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11196 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
11198 if (skip_once != test_data[i].format)
11200 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
11201 skip_once = test_data[i].format;
11203 continue;
11206 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
11207 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
11208 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
11209 * second luminance value, resulting in an incorrect color in the right pixel. */
11210 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
11211 D3DPOOL_DEFAULT, &surface, NULL);
11212 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
11215 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11216 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
11217 ((DWORD *)lr.pBits)[0] = test_data[i].in;
11218 ((DWORD *)lr.pBits)[1] = 0x00800080;
11219 hr = IDirect3DSurface9_UnlockRect(surface);
11220 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
11222 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11223 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11225 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
11227 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11228 * although we asked for point filtering. Be careful when reading the results and use the pixel
11229 * centers. In the future we may want to add tests for the filtered pixels as well.
11231 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11232 * vastly differently, so we need a max diff of 18. */
11233 color = getPixelColor(device, 1, 240);
11234 ok(color_match(color, test_data[i].left, 18),
11235 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
11236 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
11237 color = getPixelColor(device, 318, 240);
11238 ok(color_match(color, test_data[i].right, 18),
11239 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
11240 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
11241 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11242 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11243 IDirect3DSurface9_Release(surface);
11246 IDirect3DSurface9_Release(target);
11247 refcount = IDirect3DDevice9_Release(device);
11248 ok(!refcount, "Device has %u references left.\n", refcount);
11249 done:
11250 IDirect3D9_Release(d3d);
11251 DestroyWindow(window);
11254 static void yuv_layout_test(void)
11256 HRESULT hr;
11257 IDirect3DSurface9 *surface, *target;
11258 unsigned int fmt, i, x, y;
11259 D3DFORMAT format;
11260 const char *fmt_string;
11261 D3DLOCKED_RECT lr;
11262 IDirect3D9 *d3d;
11263 D3DCOLOR color;
11264 DWORD ref_color;
11265 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
11266 UINT width = 20, height = 16;
11267 IDirect3DDevice9 *device;
11268 ULONG refcount;
11269 D3DCAPS9 caps;
11270 D3DSURFACE_DESC desc;
11271 HWND window;
11273 static const struct
11275 DWORD color1, color2;
11276 DWORD rgb1, rgb2;
11278 test_data[] =
11280 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
11281 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
11282 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
11283 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
11284 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
11285 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
11286 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
11287 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
11290 static const struct
11292 D3DFORMAT format;
11293 const char *str;
11295 formats[] =
11297 { D3DFMT_UYVY, "D3DFMT_UYVY", },
11298 { D3DFMT_YUY2, "D3DFMT_YUY2", },
11299 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
11300 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
11303 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11304 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11305 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11306 ok(!!d3d, "Failed to create a D3D object.\n");
11307 if (!(device = create_device(d3d, window, window, TRUE)))
11309 skip("Failed to create a D3D device, skipping tests.\n");
11310 goto done;
11313 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11314 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11315 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
11316 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
11318 skip("No NP2 texture support, skipping YUV texture layout test.\n");
11319 IDirect3DDevice9_Release(device);
11320 goto done;
11323 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11324 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
11325 hr = IDirect3DSurface9_GetDesc(target, &desc);
11326 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11328 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
11330 format = formats[fmt].format;
11331 fmt_string = formats[fmt].str;
11333 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
11334 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
11335 * of drawPrimitive. */
11336 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
11337 D3DRTYPE_SURFACE, format) != D3D_OK)
11339 skip("%s is not supported.\n", fmt_string);
11340 continue;
11342 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11343 D3DDEVTYPE_HAL, format, desc.Format)))
11345 skip("Driver cannot blit %s surfaces.\n", fmt_string);
11346 continue;
11349 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
11350 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
11352 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11354 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11355 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
11356 buf = lr.pBits;
11357 chroma_buf = buf + lr.Pitch * height;
11358 if (format == MAKEFOURCC('Y','V','1','2'))
11360 v_buf = chroma_buf;
11361 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
11363 /* Draw the top left quarter of the screen with color1, the rest with color2 */
11364 for (y = 0; y < height; y++)
11366 for (x = 0; x < width; x += 2)
11368 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
11369 BYTE Y = (color >> 16) & 0xff;
11370 BYTE U = (color >> 8) & 0xff;
11371 BYTE V = (color >> 0) & 0xff;
11372 if (format == D3DFMT_UYVY)
11374 buf[y * lr.Pitch + 2 * x + 0] = U;
11375 buf[y * lr.Pitch + 2 * x + 1] = Y;
11376 buf[y * lr.Pitch + 2 * x + 2] = V;
11377 buf[y * lr.Pitch + 2 * x + 3] = Y;
11379 else if (format == D3DFMT_YUY2)
11381 buf[y * lr.Pitch + 2 * x + 0] = Y;
11382 buf[y * lr.Pitch + 2 * x + 1] = U;
11383 buf[y * lr.Pitch + 2 * x + 2] = Y;
11384 buf[y * lr.Pitch + 2 * x + 3] = V;
11386 else if (format == MAKEFOURCC('Y','V','1','2'))
11388 buf[y * lr.Pitch + x + 0] = Y;
11389 buf[y * lr.Pitch + x + 1] = Y;
11390 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
11391 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
11393 else if (format == MAKEFOURCC('N','V','1','2'))
11395 buf[y * lr.Pitch + x + 0] = Y;
11396 buf[y * lr.Pitch + x + 1] = Y;
11397 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
11398 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
11402 hr = IDirect3DSurface9_UnlockRect(surface);
11403 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
11405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11406 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
11407 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11408 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
11410 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11411 * although we asked for point filtering. To prevent running into precision problems, read at points
11412 * with some margin within each quadrant.
11414 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11415 * vastly differently, so we need a max diff of 18. */
11416 for (y = 0; y < 4; y++)
11418 for (x = 0; x < 4; x++)
11420 UINT xcoord = (1 + 2 * x) * 640 / 8;
11421 UINT ycoord = (1 + 2 * y) * 480 / 8;
11422 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
11423 color = getPixelColor(device, xcoord, ycoord);
11424 ok(color_match(color, ref_color, 18),
11425 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
11426 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
11429 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11431 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
11433 IDirect3DSurface9_Release(surface);
11436 IDirect3DSurface9_Release(target);
11437 refcount = IDirect3DDevice9_Release(device);
11438 ok(!refcount, "Device has %u references left.\n", refcount);
11439 done:
11440 IDirect3D9_Release(d3d);
11441 DestroyWindow(window);
11444 static void texop_range_test(void)
11446 IDirect3DTexture9 *texture;
11447 D3DLOCKED_RECT locked_rect;
11448 IDirect3DDevice9 *device;
11449 IDirect3D9 *d3d;
11450 ULONG refcount;
11451 D3DCAPS9 caps;
11452 DWORD color;
11453 HWND window;
11454 HRESULT hr;
11456 static const struct
11458 float x, y, z;
11459 D3DCOLOR diffuse;
11461 quad[] =
11463 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11464 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11465 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11466 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
11469 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11470 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11471 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11472 ok(!!d3d, "Failed to create a D3D object.\n");
11473 if (!(device = create_device(d3d, window, window, TRUE)))
11475 skip("Failed to create a D3D device, skipping tests.\n");
11476 goto done;
11479 /* We need ADD and SUBTRACT operations */
11480 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11481 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11482 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
11484 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
11485 IDirect3DDevice9_Release(device);
11486 goto done;
11488 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
11490 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
11491 IDirect3DDevice9_Release(device);
11492 goto done;
11495 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11496 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
11497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11498 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11499 /* Stage 1: result = diffuse(=1.0) + diffuse
11500 * stage 2: result = result - tfactor(= 0.5)
11502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11503 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11504 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11505 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11506 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
11507 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11508 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
11509 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11510 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
11511 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11512 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11513 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11514 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
11515 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11518 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
11519 hr = IDirect3DDevice9_BeginScene(device);
11520 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11522 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11523 hr = IDirect3DDevice9_EndScene(device);
11524 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11526 color = getPixelColor(device, 320, 240);
11527 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
11528 color);
11529 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11530 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11532 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11533 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11534 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11535 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11536 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
11537 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11538 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11539 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11540 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11542 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
11543 * stage 2: result = result + diffuse(1.0)
11545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11546 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11547 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11548 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11549 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11550 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11551 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
11552 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11553 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
11554 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11555 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
11556 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11557 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
11558 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11560 hr = IDirect3DDevice9_BeginScene(device);
11561 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11563 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11564 hr = IDirect3DDevice9_EndScene(device);
11565 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11567 color = getPixelColor(device, 320, 240);
11568 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
11569 color);
11570 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11571 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11573 IDirect3DTexture9_Release(texture);
11574 refcount = IDirect3DDevice9_Release(device);
11575 ok(!refcount, "Device has %u references left.\n", refcount);
11576 done:
11577 IDirect3D9_Release(d3d);
11578 DestroyWindow(window);
11581 static void alphareplicate_test(void)
11583 IDirect3DDevice9 *device;
11584 IDirect3D9 *d3d;
11585 ULONG refcount;
11586 DWORD color;
11587 HWND window;
11588 HRESULT hr;
11590 static const struct vertex quad[] =
11592 {-1.0f, -1.0f, 0.1f, 0x80ff00ff},
11593 {-1.0f, 1.0f, 0.1f, 0x80ff00ff},
11594 { 1.0f, -1.0f, 0.1f, 0x80ff00ff},
11595 { 1.0f, 1.0f, 0.1f, 0x80ff00ff},
11598 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11599 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11600 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11601 ok(!!d3d, "Failed to create a D3D object.\n");
11602 if (!(device = create_device(d3d, window, window, TRUE)))
11604 skip("Failed to create a D3D device, skipping tests.\n");
11605 goto done;
11608 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11609 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11611 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11612 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11614 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11615 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11616 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
11617 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11619 hr = IDirect3DDevice9_BeginScene(device);
11620 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11621 if(SUCCEEDED(hr)) {
11622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11623 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11624 hr = IDirect3DDevice9_EndScene(device);
11625 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11628 color = getPixelColor(device, 320, 240);
11629 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
11630 color);
11631 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11632 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11634 refcount = IDirect3DDevice9_Release(device);
11635 ok(!refcount, "Device has %u references left.\n", refcount);
11636 done:
11637 IDirect3D9_Release(d3d);
11638 DestroyWindow(window);
11641 static void dp3_alpha_test(void)
11643 IDirect3DDevice9 *device;
11644 IDirect3D9 *d3d;
11645 ULONG refcount;
11646 D3DCAPS9 caps;
11647 DWORD color;
11648 HWND window;
11649 HRESULT hr;
11651 static const struct vertex quad[] =
11653 {-1.0f, -1.0f, 0.1f, 0x408080c0},
11654 {-1.0f, 1.0f, 0.1f, 0x408080c0},
11655 { 1.0f, -1.0f, 0.1f, 0x408080c0},
11656 { 1.0f, 1.0f, 0.1f, 0x408080c0},
11659 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11660 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11661 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11662 ok(!!d3d, "Failed to create a D3D object.\n");
11663 if (!(device = create_device(d3d, window, window, TRUE)))
11665 skip("Failed to create a D3D device, skipping tests.\n");
11666 goto done;
11669 memset(&caps, 0, sizeof(caps));
11670 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11671 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11672 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
11674 skip("D3DTOP_DOTPRODUCT3 not supported\n");
11675 IDirect3DDevice9_Release(device);
11676 goto done;
11679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 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);
11685 /* dp3_x4 r0, diffuse_bias, tfactor_bias
11686 * mov r0.a, diffuse.a
11687 * mov r0, r0.a
11689 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
11690 * 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
11691 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
11693 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
11694 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11695 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11696 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11697 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11699 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
11700 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11701 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
11702 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11703 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11704 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11705 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
11706 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11707 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
11708 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
11710 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11712 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11714 hr = IDirect3DDevice9_BeginScene(device);
11715 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11716 if(SUCCEEDED(hr)) {
11717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11718 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11719 hr = IDirect3DDevice9_EndScene(device);
11720 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11723 color = getPixelColor(device, 320, 240);
11724 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
11725 color);
11726 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11727 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11729 refcount = IDirect3DDevice9_Release(device);
11730 ok(!refcount, "Device has %u references left.\n", refcount);
11731 done:
11732 IDirect3D9_Release(d3d);
11733 DestroyWindow(window);
11736 static void zwriteenable_test(void)
11738 IDirect3DDevice9 *device;
11739 IDirect3D9 *d3d;
11740 D3DCOLOR color;
11741 ULONG refcount;
11742 HWND window;
11743 HRESULT hr;
11745 static const struct vertex quad1[] =
11747 {-1.0f, -1.0f, 0.1f, 0x00ff0000},
11748 {-1.0f, 1.0f, 0.1f, 0x00ff0000},
11749 { 1.0f, -1.0f, 0.1f, 0x00ff0000},
11750 { 1.0f, 1.0f, 0.1f, 0x00ff0000},
11752 static const struct vertex quad2[] =
11754 {-1.0f, -1.0f, 0.9f, 0x0000ff00},
11755 {-1.0f, 1.0f, 0.9f, 0x0000ff00},
11756 { 1.0f, -1.0f, 0.9f, 0x0000ff00},
11757 { 1.0f, 1.0f, 0.9f, 0x0000ff00},
11760 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11761 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11762 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11763 ok(!!d3d, "Failed to create a D3D object.\n");
11764 if (!(device = create_device(d3d, window, window, TRUE)))
11766 skip("Failed to create a D3D device, skipping tests.\n");
11767 goto done;
11770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
11771 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11773 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11774 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11775 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11776 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11778 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11782 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11784 hr = IDirect3DDevice9_BeginScene(device);
11785 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11786 if(SUCCEEDED(hr)) {
11787 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
11788 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
11789 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
11790 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
11791 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
11792 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
11794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11795 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11797 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11799 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11801 hr = IDirect3DDevice9_EndScene(device);
11802 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11805 color = getPixelColor(device, 320, 240);
11806 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
11807 color);
11808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11809 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11811 refcount = IDirect3DDevice9_Release(device);
11812 ok(!refcount, "Device has %u references left.\n", refcount);
11813 done:
11814 IDirect3D9_Release(d3d);
11815 DestroyWindow(window);
11818 static void alphatest_test(void)
11820 #define ALPHATEST_PASSED 0x0000ff00
11821 #define ALPHATEST_FAILED 0x00ff0000
11822 IDirect3DDevice9 *device;
11823 unsigned int i, j;
11824 IDirect3D9 *d3d;
11825 D3DCOLOR color;
11826 ULONG refcount;
11827 D3DCAPS9 caps;
11828 HWND window;
11829 HRESULT hr;
11831 static const struct
11833 D3DCMPFUNC func;
11834 D3DCOLOR color_less;
11835 D3DCOLOR color_equal;
11836 D3DCOLOR color_greater;
11838 testdata[] =
11840 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11841 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11842 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11843 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11844 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11845 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11846 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11847 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11849 static const struct vertex quad[] =
11851 {-1.0f, -1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11852 {-1.0f, 1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11853 { 1.0f, -1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11854 { 1.0f, 1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11857 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11858 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11859 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11860 ok(!!d3d, "Failed to create a D3D object.\n");
11861 if (!(device = create_device(d3d, window, window, TRUE)))
11863 skip("Failed to create a D3D device, skipping tests.\n");
11864 goto done;
11867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11868 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11871 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
11873 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11874 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11875 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11877 for (j = 0; j < 2; ++j)
11879 if (j == 1)
11881 /* Try a pixel shader instead of fixed function. The wined3d code
11882 * may emulate the alpha test either for performance reasons
11883 * (floating point RTs) or to work around driver bugs (GeForce
11884 * 7x00 cards on MacOS). There may be a different codepath for ffp
11885 * and shader in this case, and the test should cover both. */
11886 IDirect3DPixelShader9 *ps;
11887 static const DWORD shader_code[] =
11889 0xffff0101, /* ps_1_1 */
11890 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11891 0x0000ffff /* end */
11893 memset(&caps, 0, sizeof(caps));
11894 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11895 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
11896 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
11897 break;
11900 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
11901 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
11902 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11903 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
11904 IDirect3DPixelShader9_Release(ps);
11907 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
11908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
11909 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11911 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11912 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
11914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11915 hr = IDirect3DDevice9_BeginScene(device);
11916 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11917 if(SUCCEEDED(hr)) {
11918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11919 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11920 hr = IDirect3DDevice9_EndScene(device);
11921 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11923 color = getPixelColor(device, 320, 240);
11924 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
11925 color, testdata[i].color_less, testdata[i].func);
11926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11927 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11929 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11930 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
11932 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11933 hr = IDirect3DDevice9_BeginScene(device);
11934 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11935 if(SUCCEEDED(hr)) {
11936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11937 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11938 hr = IDirect3DDevice9_EndScene(device);
11939 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11941 color = getPixelColor(device, 320, 240);
11942 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
11943 color, testdata[i].color_equal, testdata[i].func);
11944 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11945 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11947 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11948 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
11950 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11951 hr = IDirect3DDevice9_BeginScene(device);
11952 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11953 if(SUCCEEDED(hr)) {
11954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11955 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11956 hr = IDirect3DDevice9_EndScene(device);
11957 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11959 color = getPixelColor(device, 320, 240);
11960 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
11961 color, testdata[i].color_greater, testdata[i].func);
11962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11963 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11967 refcount = IDirect3DDevice9_Release(device);
11968 ok(!refcount, "Device has %u references left.\n", refcount);
11969 done:
11970 IDirect3D9_Release(d3d);
11971 DestroyWindow(window);
11974 static void sincos_test(void)
11976 IDirect3DVertexShader9 *sin_shader, *cos_shader;
11977 IDirect3DDevice9 *device;
11978 struct vec3 data[1280];
11979 IDirect3D9 *d3d;
11980 unsigned int i;
11981 ULONG refcount;
11982 D3DCAPS9 caps;
11983 HWND window;
11984 HRESULT hr;
11986 static const DWORD sin_shader_code[] =
11988 0xfffe0200, /* vs_2_0 */
11989 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11990 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
11991 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
11992 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
11993 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
11994 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
11995 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
11996 0x0000ffff /* end */
11998 static const DWORD cos_shader_code[] =
12000 0xfffe0200, /* vs_2_0 */
12001 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12002 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12003 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12004 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
12005 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12006 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
12007 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
12008 0x0000ffff /* end */
12010 static const float sincosc1[4] = {D3DSINCOSCONST1};
12011 static const float sincosc2[4] = {D3DSINCOSCONST2};
12013 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12014 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12015 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12016 ok(!!d3d, "Failed to create a D3D object.\n");
12017 if (!(device = create_device(d3d, window, window, TRUE)))
12019 skip("Failed to create a D3D device, skipping tests.\n");
12020 goto done;
12023 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12024 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12025 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12027 skip("No vs_2_0 support, skipping tests.\n");
12028 IDirect3DDevice9_Release(device);
12029 goto done;
12032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12035 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
12036 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12037 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
12038 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12039 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12040 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12041 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
12042 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12043 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
12044 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12046 /* Generate a point from -1 to 1 every 0.5 pixels */
12047 for(i = 0; i < 1280; i++) {
12048 data[i].x = (-640.0 + i) / 640.0;
12049 data[i].y = 0.0;
12050 data[i].z = 0.1;
12053 hr = IDirect3DDevice9_BeginScene(device);
12054 if(SUCCEEDED(hr)) {
12055 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
12056 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
12057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12058 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
12060 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
12061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
12062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12063 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
12065 hr = IDirect3DDevice9_EndScene(device);
12066 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
12068 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12069 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
12070 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
12072 IDirect3DVertexShader9_Release(sin_shader);
12073 IDirect3DVertexShader9_Release(cos_shader);
12074 refcount = IDirect3DDevice9_Release(device);
12075 ok(!refcount, "Device has %u references left.\n", refcount);
12076 done:
12077 IDirect3D9_Release(d3d);
12078 DestroyWindow(window);
12081 static void loop_index_test(void)
12083 IDirect3DVertexShader9 *shader;
12084 IDirect3DDevice9 *device;
12085 IDirect3D9 *d3d;
12086 float values[4];
12087 ULONG refcount;
12088 D3DCAPS9 caps;
12089 DWORD color;
12090 HWND window;
12091 HRESULT hr;
12093 static const DWORD shader_code[] =
12095 0xfffe0200, /* vs_2_0 */
12096 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12097 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
12098 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
12099 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
12100 0x0000001d, /* endloop */
12101 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12102 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
12103 0x0000ffff /* END */
12105 static const float quad[] =
12107 -1.0f, -1.0f, 0.1f,
12108 -1.0f, 1.0f, 0.1f,
12109 1.0f, -1.0f, 0.1f,
12110 1.0f, 1.0f, 0.1f,
12112 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
12113 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
12114 static const int i0[4] = {2, 10, -3, 0};
12116 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12117 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12118 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12119 ok(!!d3d, "Failed to create a D3D object.\n");
12120 if (!(device = create_device(d3d, window, window, TRUE)))
12122 skip("Failed to create a D3D device, skipping tests.\n");
12123 goto done;
12126 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12127 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12128 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12130 skip("No vs_2_0 support, skipping tests.\n");
12131 IDirect3DDevice9_Release(device);
12132 goto done;
12135 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12136 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12137 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12139 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12140 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12142 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12144 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
12145 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12146 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
12147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12148 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
12149 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12150 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
12151 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12152 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
12153 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12154 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
12155 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12156 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
12157 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12158 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
12159 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12160 values[0] = 1.0;
12161 values[1] = 1.0;
12162 values[2] = 0.0;
12163 values[3] = 0.0;
12164 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
12165 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12166 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
12167 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12168 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
12169 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12170 values[0] = -1.0;
12171 values[1] = 0.0;
12172 values[2] = 0.0;
12173 values[3] = 0.0;
12174 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
12175 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12176 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
12177 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12178 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
12179 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12180 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
12181 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12182 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
12183 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12185 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
12186 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
12188 hr = IDirect3DDevice9_BeginScene(device);
12189 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
12190 if(SUCCEEDED(hr))
12192 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12193 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
12194 hr = IDirect3DDevice9_EndScene(device);
12195 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
12197 color = getPixelColor(device, 320, 240);
12198 ok(color_match(color, 0x0000ff00, 1),
12199 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
12200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12201 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12203 IDirect3DVertexShader9_Release(shader);
12204 refcount = IDirect3DDevice9_Release(device);
12205 ok(!refcount, "Device has %u references left.\n", refcount);
12206 done:
12207 IDirect3D9_Release(d3d);
12208 DestroyWindow(window);
12211 static void sgn_test(void)
12213 IDirect3DVertexShader9 *shader;
12214 IDirect3DDevice9 *device;
12215 IDirect3D9 *d3d;
12216 ULONG refcount;
12217 D3DCAPS9 caps;
12218 DWORD color;
12219 HWND window;
12220 HRESULT hr;
12222 static const DWORD shader_code[] =
12224 0xfffe0200, /* vs_2_0 */
12225 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
12226 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
12227 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
12228 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12229 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
12230 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
12231 0x0000ffff /* end */
12233 static const float quad[] =
12235 -1.0f, -1.0f, 0.1f,
12236 -1.0f, 1.0f, 0.1f,
12237 1.0f, -1.0f, 0.1f,
12238 1.0f, 1.0f, 0.1f,
12241 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12242 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12243 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12244 ok(!!d3d, "Failed to create a D3D object.\n");
12245 if (!(device = create_device(d3d, window, window, TRUE)))
12247 skip("Failed to create a D3D device, skipping tests.\n");
12248 goto done;
12251 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12252 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12253 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12255 skip("No vs_2_0 support, skipping tests.\n");
12256 IDirect3DDevice9_Release(device);
12257 goto done;
12260 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12262 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12263 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12264 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12265 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12267 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12269 hr = IDirect3DDevice9_BeginScene(device);
12270 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
12271 if(SUCCEEDED(hr))
12273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12274 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
12275 hr = IDirect3DDevice9_EndScene(device);
12276 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
12278 color = getPixelColor(device, 320, 240);
12279 ok(color_match(color, 0x008000ff, 1),
12280 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
12281 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12282 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12284 IDirect3DVertexShader9_Release(shader);
12285 refcount = IDirect3DDevice9_Release(device);
12286 ok(!refcount, "Device has %u references left.\n", refcount);
12287 done:
12288 IDirect3D9_Release(d3d);
12289 DestroyWindow(window);
12292 static void viewport_test(void)
12294 IDirect3DDevice9 *device;
12295 BOOL draw_failed = TRUE;
12296 D3DVIEWPORT9 vp;
12297 IDirect3D9 *d3d;
12298 ULONG refcount;
12299 DWORD color;
12300 HWND window;
12301 HRESULT hr;
12303 static const float quad[] =
12305 -0.5f, -0.5f, 0.1f,
12306 -0.5f, 0.5f, 0.1f,
12307 0.5f, -0.5f, 0.1f,
12308 0.5f, 0.5f, 0.1f,
12311 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12312 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12313 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12314 ok(!!d3d, "Failed to create a D3D object.\n");
12315 if (!(device = create_device(d3d, window, window, TRUE)))
12317 skip("Failed to create a D3D device, skipping tests.\n");
12318 goto done;
12321 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12322 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12324 /* Test a viewport with Width and Height bigger than the surface dimensions
12326 * TODO: Test Width < surface.width, but X + Width > surface.width
12327 * TODO: Test Width < surface.width, what happens with the height?
12329 * The expected behavior is that the viewport behaves like the "default"
12330 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
12331 * MinZ = 0.0, MaxZ = 1.0.
12333 * Starting with Windows 7 the behavior among driver versions is not
12334 * consistent. The SetViewport call is accepted on all drivers. Some
12335 * drivers(older nvidia ones) refuse to draw and return an error. Newer
12336 * nvidia drivers draw, but use the actual values in the viewport and only
12337 * display the upper left part on the surface.
12339 memset(&vp, 0, sizeof(vp));
12340 vp.X = 0;
12341 vp.Y = 0;
12342 vp.Width = 10000;
12343 vp.Height = 10000;
12344 vp.MinZ = 0.0;
12345 vp.MaxZ = 0.0;
12346 hr = IDirect3DDevice9_SetViewport(device, &vp);
12347 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
12349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12350 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12353 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
12354 hr = IDirect3DDevice9_BeginScene(device);
12355 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
12356 if(SUCCEEDED(hr))
12358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12359 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
12360 draw_failed = FAILED(hr);
12361 hr = IDirect3DDevice9_EndScene(device);
12362 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
12365 if(!draw_failed)
12367 color = getPixelColor(device, 158, 118);
12368 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
12369 color = getPixelColor(device, 162, 118);
12370 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
12371 color = getPixelColor(device, 158, 122);
12372 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
12373 color = getPixelColor(device, 162, 122);
12374 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
12376 color = getPixelColor(device, 478, 358);
12377 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
12378 color = getPixelColor(device, 482, 358);
12379 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
12380 color = getPixelColor(device, 478, 362);
12381 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
12382 color = getPixelColor(device, 482, 362);
12383 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
12386 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12387 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12389 refcount = IDirect3DDevice9_Release(device);
12390 ok(!refcount, "Device has %u references left.\n", refcount);
12391 done:
12392 IDirect3D9_Release(d3d);
12393 DestroyWindow(window);
12396 /* This test tests depth clamping / clipping behaviour:
12397 * - With software vertex processing, depth values are clamped to the
12398 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
12399 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
12400 * same as regular vertices here.
12401 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
12402 * Normal vertices are always clipped. Pretransformed vertices are
12403 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
12404 * - The viewport's MinZ/MaxZ is irrelevant for this.
12406 static void depth_clamp_test(IDirect3DDevice9 *device)
12408 const struct tvertex quad1[] =
12410 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
12411 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
12412 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
12413 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
12415 const struct tvertex quad2[] =
12417 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
12418 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
12419 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
12420 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
12422 const struct tvertex quad3[] =
12424 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
12425 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
12426 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
12427 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
12429 const struct tvertex quad4[] =
12431 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
12432 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
12433 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
12434 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
12436 const struct vertex quad5[] =
12438 { -0.5f, 0.5f, 10.0f, 0xff14f914},
12439 { 0.5f, 0.5f, 10.0f, 0xff14f914},
12440 { -0.5f, -0.5f, 10.0f, 0xff14f914},
12441 { 0.5f, -0.5f, 10.0f, 0xff14f914},
12443 const struct vertex quad6[] =
12445 { -1.0f, 0.5f, 10.0f, 0xfff91414},
12446 { 1.0f, 0.5f, 10.0f, 0xfff91414},
12447 { -1.0f, 0.25f, 10.0f, 0xfff91414},
12448 { 1.0f, 0.25f, 10.0f, 0xfff91414},
12451 D3DVIEWPORT9 vp;
12452 D3DCOLOR color;
12453 D3DCAPS9 caps;
12454 HRESULT hr;
12456 vp.X = 0;
12457 vp.Y = 0;
12458 vp.Width = 640;
12459 vp.Height = 480;
12460 vp.MinZ = 0.0;
12461 vp.MaxZ = 7.5;
12463 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12464 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12466 hr = IDirect3DDevice9_SetViewport(device, &vp);
12467 if(FAILED(hr))
12469 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
12470 * the tests because the 7.5 is just intended to show that it doesn't have
12471 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
12472 * viewport and continue.
12474 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
12475 vp.MaxZ = 1.0;
12476 hr = IDirect3DDevice9_SetViewport(device, &vp);
12478 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
12481 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12483 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
12484 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12486 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12488 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12490 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12492 hr = IDirect3DDevice9_BeginScene(device);
12493 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12495 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
12496 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12499 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12501 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12504 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12507 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
12509 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
12512 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12514 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12515 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
12518 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12521 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
12524 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12526 hr = IDirect3DDevice9_EndScene(device);
12527 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12529 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
12531 color = getPixelColor(device, 75, 75);
12532 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12533 color = getPixelColor(device, 150, 150);
12534 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12535 color = getPixelColor(device, 320, 240);
12536 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12537 color = getPixelColor(device, 320, 330);
12538 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12539 color = getPixelColor(device, 320, 330);
12540 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12542 else
12544 color = getPixelColor(device, 75, 75);
12545 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
12546 color = getPixelColor(device, 150, 150);
12547 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
12548 color = getPixelColor(device, 320, 240);
12549 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
12550 color = getPixelColor(device, 320, 330);
12551 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12552 color = getPixelColor(device, 320, 330);
12553 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12556 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12557 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12559 vp.MinZ = 0.0;
12560 vp.MaxZ = 1.0;
12561 hr = IDirect3DDevice9_SetViewport(device, &vp);
12562 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12565 static void depth_bounds_test(void)
12567 const struct tvertex quad1[] =
12569 { 0, 0, 0.0f, 1, 0xfff9e814},
12570 { 640, 0, 0.0f, 1, 0xfff9e814},
12571 { 0, 480, 1.0f, 1, 0xfff9e814},
12572 { 640, 480, 1.0f, 1, 0xfff9e814},
12574 const struct tvertex quad2[] =
12576 { 0, 0, 0.6f, 1, 0xff002b7f},
12577 { 640, 0, 0.6f, 1, 0xff002b7f},
12578 { 0, 480, 0.6f, 1, 0xff002b7f},
12579 { 640, 480, 0.6f, 1, 0xff002b7f},
12581 const struct tvertex quad3[] =
12583 { 0, 100, 0.6f, 1, 0xfff91414},
12584 { 640, 100, 0.6f, 1, 0xfff91414},
12585 { 0, 160, 0.6f, 1, 0xfff91414},
12586 { 640, 160, 0.6f, 1, 0xfff91414},
12589 union {
12590 DWORD d;
12591 float f;
12592 } tmpvalue;
12594 IDirect3DSurface9 *offscreen_surface = NULL;
12595 IDirect3DDevice9 *device;
12596 IDirect3D9 *d3d;
12597 D3DCOLOR color;
12598 ULONG refcount;
12599 HWND window;
12600 HRESULT hr;
12602 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12603 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12604 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12605 ok(!!d3d, "Failed to create a D3D object.\n");
12606 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12607 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
12609 skip("No NVDB (depth bounds test) support, skipping tests.\n");
12610 goto done;
12612 if (!(device = create_device(d3d, window, window, TRUE)))
12614 skip("Failed to create a D3D device, skipping tests.\n");
12615 goto done;
12618 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
12619 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
12620 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
12621 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
12623 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
12624 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12626 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12627 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
12629 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12631 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12633 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12636 hr = IDirect3DDevice9_BeginScene(device);
12637 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12639 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
12640 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12643 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
12646 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12648 tmpvalue.f = 0.625;
12649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
12650 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12652 tmpvalue.f = 0.75;
12653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
12654 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12657 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12659 tmpvalue.f = 0.75;
12660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
12661 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12664 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
12667 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12669 hr = IDirect3DDevice9_EndScene(device);
12670 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12672 color = getPixelColor(device, 150, 130);
12673 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12674 color = getPixelColor(device, 150, 200);
12675 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12676 color = getPixelColor(device, 150, 300-5);
12677 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12678 color = getPixelColor(device, 150, 300+5);
12679 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
12680 color = getPixelColor(device, 150, 330);
12681 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
12682 color = getPixelColor(device, 150, 360-5);
12683 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
12684 color = getPixelColor(device, 150, 360+5);
12685 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12687 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12688 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12689 refcount = IDirect3DDevice9_Release(device);
12690 ok(!refcount, "Device has %u references left.\n", refcount);
12691 done:
12692 IDirect3D9_Release(d3d);
12693 DestroyWindow(window);
12696 static void depth_buffer_test(void)
12698 static const struct vertex quad1[] =
12700 { -1.0, 1.0, 0.33f, 0xff00ff00},
12701 { 1.0, 1.0, 0.33f, 0xff00ff00},
12702 { -1.0, -1.0, 0.33f, 0xff00ff00},
12703 { 1.0, -1.0, 0.33f, 0xff00ff00},
12705 static const struct vertex quad2[] =
12707 { -1.0, 1.0, 0.50f, 0xffff00ff},
12708 { 1.0, 1.0, 0.50f, 0xffff00ff},
12709 { -1.0, -1.0, 0.50f, 0xffff00ff},
12710 { 1.0, -1.0, 0.50f, 0xffff00ff},
12712 static const struct vertex quad3[] =
12714 { -1.0, 1.0, 0.66f, 0xffff0000},
12715 { 1.0, 1.0, 0.66f, 0xffff0000},
12716 { -1.0, -1.0, 0.66f, 0xffff0000},
12717 { 1.0, -1.0, 0.66f, 0xffff0000},
12719 static const DWORD expected_colors[4][4] =
12721 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12722 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12723 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
12724 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12727 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
12728 IDirect3DDevice9 *device;
12729 unsigned int i, j;
12730 D3DVIEWPORT9 vp;
12731 IDirect3D9 *d3d;
12732 D3DCOLOR color;
12733 ULONG refcount;
12734 HWND window;
12735 HRESULT hr;
12737 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12738 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12739 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12740 ok(!!d3d, "Failed to create a D3D object.\n");
12741 if (!(device = create_device(d3d, window, window, TRUE)))
12743 skip("Failed to create a D3D device, skipping tests.\n");
12744 goto done;
12747 vp.X = 0;
12748 vp.Y = 0;
12749 vp.Width = 640;
12750 vp.Height = 480;
12751 vp.MinZ = 0.0;
12752 vp.MaxZ = 1.0;
12754 hr = IDirect3DDevice9_SetViewport(device, &vp);
12755 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12758 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12760 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12762 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12764 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12765 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12766 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12768 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12769 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12770 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
12771 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
12772 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12773 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
12774 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
12775 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12776 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12777 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
12778 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12780 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
12781 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12782 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
12783 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12785 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12786 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12788 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12790 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
12791 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12792 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
12793 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12795 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
12796 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12797 hr = IDirect3DDevice9_BeginScene(device);
12798 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12800 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12801 hr = IDirect3DDevice9_EndScene(device);
12802 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12804 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12805 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12808 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12810 hr = IDirect3DDevice9_BeginScene(device);
12811 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12813 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12815 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12816 hr = IDirect3DDevice9_EndScene(device);
12817 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12819 for (i = 0; i < 4; ++i)
12821 for (j = 0; j < 4; ++j)
12823 unsigned int x = 80 * ((2 * j) + 1);
12824 unsigned int y = 60 * ((2 * i) + 1);
12825 color = getPixelColor(device, x, y);
12826 ok(color_match(color, expected_colors[i][j], 0),
12827 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
12831 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12832 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12834 IDirect3DSurface9_Release(backbuffer);
12835 IDirect3DSurface9_Release(rt3);
12836 IDirect3DSurface9_Release(rt2);
12837 IDirect3DSurface9_Release(rt1);
12838 refcount = IDirect3DDevice9_Release(device);
12839 ok(!refcount, "Device has %u references left.\n", refcount);
12840 done:
12841 IDirect3D9_Release(d3d);
12842 DestroyWindow(window);
12845 /* Test that partial depth copies work the way they're supposed to. The clear
12846 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
12847 * the following draw should only copy back the part that was modified. */
12848 static void depth_buffer2_test(void)
12850 static const struct vertex quad[] =
12852 { -1.0, 1.0, 0.66f, 0xffff0000},
12853 { 1.0, 1.0, 0.66f, 0xffff0000},
12854 { -1.0, -1.0, 0.66f, 0xffff0000},
12855 { 1.0, -1.0, 0.66f, 0xffff0000},
12858 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
12859 IDirect3DDevice9 *device;
12860 unsigned int i, j;
12861 D3DVIEWPORT9 vp;
12862 IDirect3D9 *d3d;
12863 D3DCOLOR color;
12864 ULONG refcount;
12865 HWND window;
12866 HRESULT hr;
12868 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12869 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12870 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12871 ok(!!d3d, "Failed to create a D3D object.\n");
12872 if (!(device = create_device(d3d, window, window, TRUE)))
12874 skip("Failed to create a D3D device, skipping tests.\n");
12875 goto done;
12878 vp.X = 0;
12879 vp.Y = 0;
12880 vp.Width = 640;
12881 vp.Height = 480;
12882 vp.MinZ = 0.0;
12883 vp.MaxZ = 1.0;
12885 hr = IDirect3DDevice9_SetViewport(device, &vp);
12886 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12889 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12891 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12893 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12895 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12896 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12897 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12899 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12900 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
12901 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12902 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
12903 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
12904 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12905 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12906 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12908 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
12909 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12911 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12913 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12914 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12915 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
12916 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12918 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
12919 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
12921 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12923 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12924 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12927 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12929 hr = IDirect3DDevice9_BeginScene(device);
12930 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12932 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12933 hr = IDirect3DDevice9_EndScene(device);
12934 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12936 for (i = 0; i < 4; ++i)
12938 for (j = 0; j < 4; ++j)
12940 unsigned int x = 80 * ((2 * j) + 1);
12941 unsigned int y = 60 * ((2 * i) + 1);
12942 color = getPixelColor(device, x, y);
12943 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
12944 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
12948 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12949 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12951 IDirect3DSurface9_Release(backbuffer);
12952 IDirect3DSurface9_Release(rt2);
12953 IDirect3DSurface9_Release(rt1);
12954 refcount = IDirect3DDevice9_Release(device);
12955 ok(!refcount, "Device has %u references left.\n", refcount);
12956 done:
12957 IDirect3D9_Release(d3d);
12958 DestroyWindow(window);
12961 static void depth_blit_test(void)
12963 static const struct vertex quad1[] =
12965 { -1.0, 1.0, 0.33f, 0xff00ff00},
12966 { 1.0, 1.0, 0.33f, 0xff00ff00},
12967 { -1.0, -1.0, 0.33f, 0xff00ff00},
12968 { 1.0, -1.0, 0.33f, 0xff00ff00},
12970 static const struct vertex quad2[] =
12972 { -1.0, 1.0, 0.66f, 0xff0000ff},
12973 { 1.0, 1.0, 0.66f, 0xff0000ff},
12974 { -1.0, -1.0, 0.66f, 0xff0000ff},
12975 { 1.0, -1.0, 0.66f, 0xff0000ff},
12977 static const DWORD expected_colors[4][4] =
12979 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12980 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12981 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
12982 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12985 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
12986 IDirect3DDevice9 *device;
12987 RECT src_rect, dst_rect;
12988 unsigned int i, j;
12989 D3DVIEWPORT9 vp;
12990 IDirect3D9 *d3d;
12991 D3DCOLOR color;
12992 ULONG refcount;
12993 HWND window;
12994 HRESULT hr;
12996 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12997 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12998 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12999 ok(!!d3d, "Failed to create a D3D object.\n");
13000 if (!(device = create_device(d3d, window, window, TRUE)))
13002 skip("Failed to create a D3D device, skipping tests.\n");
13003 goto done;
13006 vp.X = 0;
13007 vp.Y = 0;
13008 vp.Width = 640;
13009 vp.Height = 480;
13010 vp.MinZ = 0.0;
13011 vp.MaxZ = 1.0;
13013 hr = IDirect3DDevice9_SetViewport(device, &vp);
13014 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13016 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13017 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13018 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
13019 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13020 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
13021 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13022 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
13023 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13024 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
13025 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13028 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13030 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13032 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13033 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13034 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13036 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13037 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13038 SetRect(&dst_rect, 0, 0, 480, 360);
13039 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
13040 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13041 SetRect(&dst_rect, 0, 0, 320, 240);
13042 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13043 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13045 /* Partial blit. */
13046 SetRect(&src_rect, 0, 0, 320, 240);
13047 SetRect(&dst_rect, 0, 0, 320, 240);
13048 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13049 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13050 /* Flipped. */
13051 SetRect(&src_rect, 0, 0, 640, 480);
13052 SetRect(&dst_rect, 0, 480, 640, 0);
13053 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13054 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13055 /* Full, explicit. */
13056 SetRect(&src_rect, 0, 0, 640, 480);
13057 SetRect(&dst_rect, 0, 0, 640, 480);
13058 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13059 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13060 /* Filtered blit. */
13061 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
13062 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13063 /* Depth -> color blit.*/
13064 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
13065 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13066 IDirect3DSurface9_Release(backbuffer);
13067 /* Full surface, different sizes */
13068 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
13069 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13070 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
13071 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13073 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
13074 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
13076 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13077 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
13078 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13081 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13082 hr = IDirect3DDevice9_BeginScene(device);
13083 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13085 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13087 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13088 hr = IDirect3DDevice9_EndScene(device);
13089 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13091 for (i = 0; i < 4; ++i)
13093 for (j = 0; j < 4; ++j)
13095 unsigned int x = 80 * ((2 * j) + 1);
13096 unsigned int y = 60 * ((2 * i) + 1);
13097 color = getPixelColor(device, x, y);
13098 ok(color_match(color, expected_colors[i][j], 0),
13099 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13103 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13104 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13106 IDirect3DSurface9_Release(ds3);
13107 IDirect3DSurface9_Release(ds2);
13108 IDirect3DSurface9_Release(ds1);
13109 refcount = IDirect3DDevice9_Release(device);
13110 ok(!refcount, "Device has %u references left.\n", refcount);
13111 done:
13112 IDirect3D9_Release(d3d);
13113 DestroyWindow(window);
13116 static void intz_test(void)
13118 static const DWORD ps_code[] =
13120 0xffff0200, /* ps_2_0 */
13121 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13122 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13123 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13124 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13125 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13126 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13127 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13128 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13129 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
13130 0x0000ffff, /* end */
13132 struct
13134 float x, y, z;
13135 float s, t, p, q;
13137 quad[] =
13139 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13140 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13141 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13142 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13144 half_quad_1[] =
13146 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13147 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13148 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13149 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13151 half_quad_2[] =
13153 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
13154 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
13155 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
13156 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
13158 struct
13160 UINT x, y;
13161 D3DCOLOR color;
13163 expected_colors[] =
13165 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13166 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13167 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13168 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13169 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
13170 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
13171 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
13172 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
13175 IDirect3DSurface9 *original_rt, *rt;
13176 IDirect3DTexture9 *texture;
13177 IDirect3DPixelShader9 *ps;
13178 IDirect3DDevice9 *device;
13179 IDirect3DSurface9 *ds;
13180 IDirect3D9 *d3d;
13181 ULONG refcount;
13182 D3DCAPS9 caps;
13183 HWND window;
13184 HRESULT hr;
13185 UINT i;
13187 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13188 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13189 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13190 ok(!!d3d, "Failed to create a D3D object.\n");
13191 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13192 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
13194 skip("No INTZ support, skipping INTZ test.\n");
13195 goto done;
13197 if (!(device = create_device(d3d, window, window, TRUE)))
13199 skip("Failed to create a D3D device, skipping tests.\n");
13200 goto done;
13203 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13204 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13205 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13207 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13208 IDirect3DDevice9_Release(device);
13209 goto done;
13211 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13213 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13214 IDirect3DDevice9_Release(device);
13215 goto done;
13218 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13219 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13221 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13222 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13223 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13224 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13225 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13226 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13227 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13228 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13230 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13231 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13232 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13233 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13239 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13241 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13242 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13243 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13244 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13246 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13247 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13248 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13249 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13250 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13252 /* Render offscreen, using the INTZ texture as depth buffer */
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_SetRenderTarget(device, 0, rt);
13258 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13259 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13260 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13262 /* Setup the depth/stencil surface. */
13263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13264 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13266 hr = IDirect3DDevice9_BeginScene(device);
13267 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13269 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13270 hr = IDirect3DDevice9_EndScene(device);
13271 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13273 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13274 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13275 IDirect3DSurface9_Release(ds);
13276 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13277 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13278 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13279 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13280 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13281 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13283 /* Read the depth values back. */
13284 hr = IDirect3DDevice9_BeginScene(device);
13285 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13287 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13288 hr = IDirect3DDevice9_EndScene(device);
13289 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13291 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13293 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13294 ok(color_match(color, expected_colors[i].color, 1),
13295 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13296 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13299 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13300 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13302 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13303 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13304 IDirect3DTexture9_Release(texture);
13306 /* Render onscreen while using the INTZ texture as depth buffer */
13307 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13308 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13309 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13310 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13311 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13312 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13313 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13314 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13316 /* Setup the depth/stencil surface. */
13317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13318 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13320 hr = IDirect3DDevice9_BeginScene(device);
13321 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13322 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13323 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13324 hr = IDirect3DDevice9_EndScene(device);
13325 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13327 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13328 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13329 IDirect3DSurface9_Release(ds);
13330 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13331 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13332 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13333 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13335 /* Read the depth values back. */
13336 hr = IDirect3DDevice9_BeginScene(device);
13337 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13339 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13340 hr = IDirect3DDevice9_EndScene(device);
13341 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13343 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13345 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13346 ok(color_match(color, expected_colors[i].color, 1),
13347 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13348 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13351 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13352 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13354 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13355 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13356 IDirect3DTexture9_Release(texture);
13358 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
13359 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13360 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13361 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13362 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13364 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13365 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13366 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13367 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13368 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13369 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13371 /* Setup the depth/stencil surface. */
13372 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13373 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13375 hr = IDirect3DDevice9_BeginScene(device);
13376 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13377 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
13378 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13379 hr = IDirect3DDevice9_EndScene(device);
13380 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13382 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13383 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13385 hr = IDirect3DDevice9_BeginScene(device);
13386 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
13388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13389 hr = IDirect3DDevice9_EndScene(device);
13390 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13392 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13393 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13394 IDirect3DSurface9_Release(ds);
13395 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13396 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13397 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13398 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13400 /* Read the depth values back. */
13401 hr = IDirect3DDevice9_BeginScene(device);
13402 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13405 hr = IDirect3DDevice9_EndScene(device);
13406 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13408 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13410 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13411 ok(color_match(color, expected_colors[i].color, 1),
13412 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13413 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13416 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13417 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13419 IDirect3DTexture9_Release(texture);
13420 IDirect3DPixelShader9_Release(ps);
13421 IDirect3DSurface9_Release(original_rt);
13422 IDirect3DSurface9_Release(rt);
13423 refcount = IDirect3DDevice9_Release(device);
13424 ok(!refcount, "Device has %u references left.\n", refcount);
13425 done:
13426 IDirect3D9_Release(d3d);
13427 DestroyWindow(window);
13430 static void shadow_test(void)
13432 static const DWORD ps_code[] =
13434 0xffff0200, /* ps_2_0 */
13435 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13436 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13437 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13438 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13439 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13440 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13441 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13442 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13443 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
13444 0x0000ffff, /* end */
13446 struct
13448 D3DFORMAT format;
13449 const char *name;
13451 formats[] =
13453 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
13454 {D3DFMT_D32, "D3DFMT_D32"},
13455 {D3DFMT_D15S1, "D3DFMT_D15S1"},
13456 {D3DFMT_D24S8, "D3DFMT_D24S8"},
13457 {D3DFMT_D24X8, "D3DFMT_D24X8"},
13458 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
13459 {D3DFMT_D16, "D3DFMT_D16"},
13460 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
13461 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
13463 struct
13465 float x, y, z;
13466 float s, t, p, q;
13468 quad[] =
13470 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
13471 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
13472 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
13473 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
13475 struct
13477 UINT x, y;
13478 D3DCOLOR color;
13480 expected_colors[] =
13482 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13483 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13484 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13485 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13486 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13487 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13488 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13489 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13492 IDirect3DSurface9 *original_ds, *original_rt, *rt;
13493 IDirect3DPixelShader9 *ps;
13494 IDirect3DDevice9 *device;
13495 IDirect3D9 *d3d;
13496 ULONG refcount;
13497 D3DCAPS9 caps;
13498 HWND window;
13499 HRESULT hr;
13500 UINT i;
13502 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13503 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13504 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13505 ok(!!d3d, "Failed to create a D3D object.\n");
13506 if (!(device = create_device(d3d, window, window, TRUE)))
13508 skip("Failed to create a D3D device, skipping tests.\n");
13509 goto done;
13512 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13513 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13514 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13516 skip("No pixel shader 2.0 support, skipping shadow test.\n");
13517 IDirect3DDevice9_Release(device);
13518 goto done;
13521 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13522 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13523 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13524 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13526 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
13527 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13528 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13530 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13533 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13535 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13537 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13539 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13541 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13543 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13544 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13545 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13546 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13547 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13548 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13549 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13550 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13551 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13552 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13554 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
13556 D3DFORMAT format = formats[i].format;
13557 IDirect3DTexture9 *texture;
13558 IDirect3DSurface9 *ds;
13559 unsigned int j;
13561 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13562 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
13563 continue;
13565 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
13566 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
13567 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13569 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13570 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13572 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13573 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13575 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13576 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13578 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13579 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13581 /* Setup the depth/stencil surface. */
13582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13583 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13585 hr = IDirect3DDevice9_BeginScene(device);
13586 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13588 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13589 hr = IDirect3DDevice9_EndScene(device);
13590 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13592 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13593 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13594 IDirect3DSurface9_Release(ds);
13596 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13597 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13599 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13600 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13602 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13603 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13605 /* Do the actual shadow mapping. */
13606 hr = IDirect3DDevice9_BeginScene(device);
13607 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13609 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13610 hr = IDirect3DDevice9_EndScene(device);
13611 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13613 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13614 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13615 IDirect3DTexture9_Release(texture);
13617 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
13619 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
13620 ok(color_match(color, expected_colors[j].color, 0),
13621 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
13622 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
13623 formats[i].name, color);
13626 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13627 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13630 IDirect3DPixelShader9_Release(ps);
13631 IDirect3DSurface9_Release(original_ds);
13632 IDirect3DSurface9_Release(original_rt);
13633 IDirect3DSurface9_Release(rt);
13634 refcount = IDirect3DDevice9_Release(device);
13635 ok(!refcount, "Device has %u references left.\n", refcount);
13636 done:
13637 IDirect3D9_Release(d3d);
13638 DestroyWindow(window);
13641 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
13643 static const struct vertex quad1[] =
13645 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
13646 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
13647 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
13648 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
13650 static const struct vertex quad2[] =
13652 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
13653 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
13654 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
13655 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
13657 D3DCOLOR color;
13658 HRESULT hr;
13660 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
13661 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13663 hr = IDirect3DDevice9_BeginScene(device);
13664 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13666 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13667 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
13670 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13672 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
13675 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13677 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13679 hr = IDirect3DDevice9_EndScene(device);
13680 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13682 color = getPixelColor(device, 1, 240);
13683 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
13684 color = getPixelColor(device, 638, 240);
13685 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
13687 color = getPixelColor(device, 1, 241);
13688 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
13689 color = getPixelColor(device, 638, 241);
13690 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
13693 static void clip_planes_test(void)
13695 IDirect3DSurface9 *offscreen_surface, *original_rt;
13696 IDirect3DTexture9 *offscreen = NULL;
13697 IDirect3DVertexShader9 *shader;
13698 IDirect3DDevice9 *device;
13699 IDirect3D9 *d3d;
13700 ULONG refcount;
13701 D3DCAPS9 caps;
13702 HWND window;
13703 HRESULT hr;
13705 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
13706 static const DWORD shader_code[] =
13708 0xfffe0200, /* vs_2_0 */
13709 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13710 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
13711 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13712 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
13713 0x0000ffff /* end */
13716 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13717 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13718 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13719 ok(!!d3d, "Failed to create a D3D object.\n");
13720 if (!(device = create_device(d3d, window, window, TRUE)))
13722 skip("Failed to create a D3D device, skipping tests.\n");
13723 goto done;
13726 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13727 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13728 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13730 skip("No vs_2_0 support, skipping tests.\n");
13731 IDirect3DDevice9_Release(device);
13732 goto done;
13735 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13736 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13739 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13741 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13743 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13745 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13747 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13748 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
13749 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13750 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
13752 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
13754 clip_planes(device, "Onscreen FFP");
13756 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
13757 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13758 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
13759 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13760 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
13761 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13763 clip_planes(device, "Offscreen FFP");
13765 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13766 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13768 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13769 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
13770 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
13773 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13774 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13776 clip_planes(device, "Onscreen vertex shader");
13778 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
13779 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13781 clip_planes(device, "Offscreen vertex shader");
13783 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13784 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13786 IDirect3DVertexShader9_Release(shader);
13787 IDirect3DSurface9_Release(original_rt);
13788 IDirect3DSurface9_Release(offscreen_surface);
13789 IDirect3DTexture9_Release(offscreen);
13790 refcount = IDirect3DDevice9_Release(device);
13791 ok(!refcount, "Device has %u references left.\n", refcount);
13792 done:
13793 IDirect3D9_Release(d3d);
13794 DestroyWindow(window);
13797 static void fp_special_test(void)
13799 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
13800 static const DWORD vs_header[] =
13802 0xfffe0200, /* vs_2_0 */
13803 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
13804 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
13805 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13806 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
13809 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
13810 static const DWORD vs_pow[] =
13811 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
13812 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
13813 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
13814 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
13815 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
13816 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
13817 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
13818 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
13819 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
13820 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
13821 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
13823 static const DWORD vs_footer[] =
13825 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
13826 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
13827 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
13828 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
13829 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
13830 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
13831 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
13832 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
13833 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
13834 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
13835 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
13836 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
13837 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
13838 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
13839 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13840 0x0000ffff, /* end */
13843 static const struct
13845 const char *name;
13846 const DWORD *ops;
13847 DWORD size;
13848 D3DCOLOR r500;
13849 D3DCOLOR r600;
13850 D3DCOLOR nv40;
13851 D3DCOLOR nv50;
13852 D3DCOLOR warp;
13854 vs_body[] =
13856 /* The basic ideas here are:
13857 * 2.0 * +/-INF == +/-INF
13858 * NAN != NAN
13860 * The vertex shader value is written to the red component, with 0.0
13861 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
13862 * result in 0x00. The pixel shader value is written to the green
13863 * component, but here 0.0 also results in 0x00. The actual value is
13864 * written to the blue component.
13866 * There are considerable differences between graphics cards in how
13867 * these are handled, but pow and nrm never generate INF or NAN on
13868 * real hardware. */
13869 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13870 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
13871 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
13872 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13873 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13874 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13875 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13876 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13877 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
13878 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13879 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13882 static const DWORD ps_code[] =
13884 0xffff0200, /* ps_2_0 */
13885 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
13886 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
13887 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
13888 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
13889 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
13890 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
13891 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
13892 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
13893 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
13894 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
13895 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
13896 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
13897 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
13898 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
13899 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
13900 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
13901 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
13902 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
13903 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
13904 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
13905 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
13906 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
13907 0x0000ffff, /* end */
13910 struct
13912 float x, y, z;
13913 float s;
13915 quad[] =
13917 { -1.0f, 1.0f, 0.0f, 0.0f},
13918 { 1.0f, 1.0f, 1.0f, 0.0f},
13919 { -1.0f, -1.0f, 0.0f, 0.0f},
13920 { 1.0f, -1.0f, 1.0f, 0.0f},
13923 IDirect3DPixelShader9 *ps;
13924 IDirect3DDevice9 *device;
13925 UINT body_size = 0;
13926 IDirect3D9 *d3d;
13927 DWORD *vs_code;
13928 ULONG refcount;
13929 D3DCAPS9 caps;
13930 HWND window;
13931 HRESULT hr;
13932 UINT i;
13934 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13935 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13936 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13937 ok(!!d3d, "Failed to create a D3D object.\n");
13938 if (!(device = create_device(d3d, window, window, TRUE)))
13940 skip("Failed to create a D3D device, skipping tests.\n");
13941 goto done;
13944 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13945 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13946 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13948 skip("No shader model 2.0 support, skipping floating point specials test.\n");
13949 IDirect3DDevice9_Release(device);
13950 goto done;
13953 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
13954 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13956 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13957 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13958 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13959 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13962 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13964 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
13965 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13967 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
13969 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
13972 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
13973 memcpy(vs_code, vs_header, sizeof(vs_header));
13975 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
13977 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
13978 IDirect3DVertexShader9 *vs;
13979 D3DCOLOR color;
13981 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
13982 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
13983 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
13985 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13986 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
13987 hr = IDirect3DDevice9_SetVertexShader(device, vs);
13988 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
13990 hr = IDirect3DDevice9_BeginScene(device);
13991 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13992 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13993 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13994 hr = IDirect3DDevice9_EndScene(device);
13995 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13997 color = getPixelColor(device, 320, 240);
13998 ok(color_match(color, vs_body[i].r500, 1)
13999 || color_match(color, vs_body[i].r600, 1)
14000 || color_match(color, vs_body[i].nv40, 1)
14001 || color_match(color, vs_body[i].nv50, 1)
14002 || broken(color_match(color, vs_body[i].warp, 1)),
14003 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
14004 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
14006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14007 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14009 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14010 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14011 IDirect3DVertexShader9_Release(vs);
14014 HeapFree(GetProcessHeap(), 0, vs_code);
14016 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14017 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14018 IDirect3DPixelShader9_Release(ps);
14019 refcount = IDirect3DDevice9_Release(device);
14020 ok(!refcount, "Device has %u references left.\n", refcount);
14021 done:
14022 IDirect3D9_Release(d3d);
14023 DestroyWindow(window);
14026 static void srgbwrite_format_test(void)
14028 IDirect3D9 *d3d;
14029 IDirect3DSurface9 *rt, *backbuffer;
14030 IDirect3DTexture9 *texture;
14031 IDirect3DDevice9 *device;
14032 ULONG refcount;
14033 HWND window;
14034 HRESULT hr;
14035 int i;
14036 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
14037 static const struct
14039 D3DFORMAT fmt;
14040 const char *name;
14042 formats[] =
14044 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
14045 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
14046 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
14047 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
14048 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
14050 static const struct
14052 float x, y, z;
14053 float u, v;
14055 quad[] =
14057 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14058 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14059 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14060 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14063 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14064 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14065 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14066 ok(!!d3d, "Failed to create a D3D object.\n");
14067 if (!(device = create_device(d3d, window, window, TRUE)))
14069 skip("Failed to create a D3D device, skipping tests.\n");
14070 goto done;
14073 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
14074 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14075 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
14076 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
14077 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14078 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
14080 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14082 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
14084 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14085 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
14087 skip("Format %s not supported as render target, skipping test.\n",
14088 formats[i].name);
14089 continue;
14092 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
14093 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
14094 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14095 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14096 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14098 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
14099 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14100 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14101 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
14103 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14105 hr = IDirect3DDevice9_BeginScene(device);
14106 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14107 if(SUCCEEDED(hr))
14109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
14110 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14111 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
14112 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14114 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
14116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
14117 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14118 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14119 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14120 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
14121 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14122 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14123 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14125 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
14126 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14127 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14129 hr = IDirect3DDevice9_EndScene(device);
14130 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14133 IDirect3DSurface9_Release(rt);
14134 IDirect3DTexture9_Release(texture);
14136 color = getPixelColor(device, 360, 240);
14137 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14138 D3DUSAGE_QUERY_SRGBWRITE,
14139 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
14141 /* Big slop for R5G6B5 */
14142 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
14143 formats[i].name, color_srgb, color);
14145 else
14147 /* Big slop for R5G6B5 */
14148 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
14149 formats[i].name, color_rgb, color);
14152 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14153 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14156 IDirect3DSurface9_Release(backbuffer);
14157 refcount = IDirect3DDevice9_Release(device);
14158 ok(!refcount, "Device has %u references left.\n", refcount);
14159 done:
14160 IDirect3D9_Release(d3d);
14161 DestroyWindow(window);
14164 static void ds_size_test(IDirect3DDevice9 *device)
14166 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
14167 HRESULT hr;
14168 DWORD num_passes;
14169 struct
14171 float x, y, z;
14173 quad[] =
14175 {-1.0, -1.0, 0.0 },
14176 {-1.0, 1.0, 0.0 },
14177 { 1.0, -1.0, 0.0 },
14178 { 1.0, 1.0, 0.0 }
14181 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14182 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14183 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
14184 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
14185 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
14186 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
14188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14189 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14190 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
14191 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14192 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14193 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14194 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14195 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14196 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14197 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14198 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
14199 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
14200 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14201 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14202 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14203 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14204 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14205 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14207 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
14208 * but does not change the surface's contents. */
14209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
14210 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
14211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
14212 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
14213 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
14214 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
14216 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
14218 /* Turning on any depth-related state results in a ValidateDevice failure */
14219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14220 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14221 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14222 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14223 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14224 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14225 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14227 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14228 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14229 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14230 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14232 /* Try to draw with the device in an invalid state */
14233 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14234 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
14235 hr = IDirect3DDevice9_BeginScene(device);
14236 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14237 if(SUCCEEDED(hr))
14239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14240 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14241 hr = IDirect3DDevice9_EndScene(device);
14242 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14244 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
14245 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
14246 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
14249 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
14250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14251 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
14252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14253 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14254 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14256 IDirect3DSurface9_Release(readback);
14257 IDirect3DSurface9_Release(ds);
14258 IDirect3DSurface9_Release(rt);
14259 IDirect3DSurface9_Release(old_rt);
14260 IDirect3DSurface9_Release(old_ds);
14263 static void unbound_sampler_test(void)
14265 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
14266 IDirect3DSurface9 *rt, *old_rt;
14267 IDirect3DDevice9 *device;
14268 IDirect3D9 *d3d;
14269 ULONG refcount;
14270 D3DCAPS9 caps;
14271 DWORD color;
14272 HWND window;
14273 HRESULT hr;
14275 static const DWORD ps_code[] =
14277 0xffff0200, /* ps_2_0 */
14278 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14279 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14280 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14281 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14282 0x0000ffff, /* end */
14284 static const DWORD ps_code_cube[] =
14286 0xffff0200, /* ps_2_0 */
14287 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
14288 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14289 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14290 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14291 0x0000ffff, /* end */
14293 static const DWORD ps_code_volume[] =
14295 0xffff0200, /* ps_2_0 */
14296 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
14297 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14298 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14299 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14300 0x0000ffff, /* end */
14303 static const struct
14305 float x, y, z;
14306 float u, v;
14308 quad[] =
14310 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14311 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14312 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14313 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14316 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14317 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14318 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14319 ok(!!d3d, "Failed to create a D3D object.\n");
14320 if (!(device = create_device(d3d, window, window, TRUE)))
14322 skip("Failed to create a D3D device, skipping tests.\n");
14323 goto done;
14326 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14327 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14328 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14330 skip("No ps_2_0 support, skipping tests.\n");
14331 IDirect3DDevice9_Release(device);
14332 goto done;
14334 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
14336 skip("No cube / volume texture support, skipping tests.\n");
14337 IDirect3DDevice9_Release(device);
14338 goto done;
14341 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14342 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
14344 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14345 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14346 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
14347 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14348 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
14349 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14351 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
14352 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14354 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14355 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14357 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14358 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14360 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
14361 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
14363 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
14364 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
14366 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14367 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14369 hr = IDirect3DDevice9_BeginScene(device);
14370 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14371 if(SUCCEEDED(hr))
14373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14374 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14376 hr = IDirect3DDevice9_EndScene(device);
14377 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14380 color = getPixelColorFromSurface(rt, 32, 32);
14381 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14383 /* Now try with a cube texture */
14384 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
14385 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14387 hr = IDirect3DDevice9_BeginScene(device);
14388 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14389 if (SUCCEEDED(hr))
14391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14392 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14394 hr = IDirect3DDevice9_EndScene(device);
14395 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14398 color = getPixelColorFromSurface(rt, 32, 32);
14399 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14401 /* And then with a volume texture */
14402 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
14403 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14405 hr = IDirect3DDevice9_BeginScene(device);
14406 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14407 if (SUCCEEDED(hr))
14409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14410 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14412 hr = IDirect3DDevice9_EndScene(device);
14413 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14416 color = getPixelColorFromSurface(rt, 32, 32);
14417 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14419 IDirect3DSurface9_Release(rt);
14420 IDirect3DSurface9_Release(old_rt);
14421 IDirect3DPixelShader9_Release(ps);
14422 IDirect3DPixelShader9_Release(ps_cube);
14423 IDirect3DPixelShader9_Release(ps_volume);
14424 refcount = IDirect3DDevice9_Release(device);
14425 ok(!refcount, "Device has %u references left.\n", refcount);
14426 done:
14427 IDirect3D9_Release(d3d);
14428 DestroyWindow(window);
14431 static void update_surface_test(void)
14433 static const BYTE blocks[][8] =
14435 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
14436 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
14437 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
14438 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
14439 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
14440 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
14441 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
14443 static const struct
14445 UINT x, y;
14446 D3DCOLOR color;
14448 expected_colors[] =
14450 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
14451 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
14452 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
14453 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
14454 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14455 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14456 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
14458 static const struct
14460 float x, y, z, w;
14461 float u, v;
14463 tri[] =
14465 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
14466 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
14467 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
14469 static const RECT rect_2x2 = {0, 0, 2, 2};
14470 static const struct
14472 UINT src_level;
14473 UINT dst_level;
14474 const RECT *r;
14475 HRESULT hr;
14477 block_size_tests[] =
14479 {1, 0, NULL, D3D_OK},
14480 {0, 1, NULL, D3DERR_INVALIDCALL},
14481 {5, 4, NULL, D3DERR_INVALIDCALL},
14482 {4, 5, NULL, D3DERR_INVALIDCALL},
14483 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
14484 {5, 5, &rect_2x2, D3D_OK},
14487 IDirect3DSurface9 *src_surface, *dst_surface;
14488 IDirect3DTexture9 *src_tex, *dst_tex;
14489 IDirect3DDevice9 *device;
14490 IDirect3D9 *d3d;
14491 ULONG refcount;
14492 UINT count, i;
14493 HWND window;
14494 HRESULT hr;
14496 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14497 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14498 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14499 ok(!!d3d, "Failed to create a D3D object.\n");
14500 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14501 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
14503 skip("DXT1 not supported, skipping tests.\n");
14504 goto done;
14506 if (!(device = create_device(d3d, window, window, TRUE)))
14508 skip("Failed to create a D3D device, skipping tests.\n");
14509 goto done;
14512 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
14513 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
14514 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
14515 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
14517 count = IDirect3DTexture9_GetLevelCount(src_tex);
14518 ok(count == 7, "Got level count %u, expected 7.\n", count);
14520 for (i = 0; i < count; ++i)
14522 UINT row_count, block_count, x, y;
14523 D3DSURFACE_DESC desc;
14524 BYTE *row, *block;
14525 D3DLOCKED_RECT r;
14527 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
14528 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
14530 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
14531 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
14533 row_count = ((desc.Height + 3) & ~3) / 4;
14534 block_count = ((desc.Width + 3) & ~3) / 4;
14535 row = r.pBits;
14537 for (y = 0; y < row_count; ++y)
14539 block = row;
14540 for (x = 0; x < block_count; ++x)
14542 memcpy(block, blocks[i], sizeof(blocks[i]));
14543 block += sizeof(blocks[i]);
14545 row += r.Pitch;
14548 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
14549 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
14552 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
14554 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
14555 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14556 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
14557 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14559 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
14560 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
14561 hr, i, block_size_tests[i].hr);
14563 IDirect3DSurface9_Release(dst_surface);
14564 IDirect3DSurface9_Release(src_surface);
14567 for (i = 0; i < count; ++i)
14569 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
14570 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14571 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
14572 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14574 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
14575 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
14577 IDirect3DSurface9_Release(dst_surface);
14578 IDirect3DSurface9_Release(src_surface);
14581 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14582 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14583 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14584 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14585 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
14586 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14587 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
14588 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14589 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14590 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14591 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14592 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14594 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
14595 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14597 hr = IDirect3DDevice9_BeginScene(device);
14598 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
14600 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14601 hr = IDirect3DDevice9_EndScene(device);
14602 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14604 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14606 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14607 ok(color_match(color, expected_colors[i].color, 0),
14608 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14609 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14612 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14613 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14615 IDirect3DTexture9_Release(dst_tex);
14616 IDirect3DTexture9_Release(src_tex);
14617 refcount = IDirect3DDevice9_Release(device);
14618 ok(!refcount, "Device has %u references left.\n", refcount);
14619 done:
14620 IDirect3D9_Release(d3d);
14621 DestroyWindow(window);
14624 static void multisample_get_rtdata_test(void)
14626 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
14627 IDirect3DDevice9 *device;
14628 IDirect3D9 *d3d;
14629 ULONG refcount;
14630 HWND window;
14631 HRESULT hr;
14633 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14634 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14635 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14636 ok(!!d3d, "Failed to create a D3D object.\n");
14637 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14638 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14640 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
14641 goto done;
14643 if (!(device = create_device(d3d, window, window, TRUE)))
14645 skip("Failed to create a D3D device, skipping tests.\n");
14646 goto done;
14649 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
14650 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14651 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14652 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
14653 D3DPOOL_SYSTEMMEM, &readback, NULL);
14654 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14656 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14657 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14658 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14659 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14661 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14662 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14663 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14664 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14666 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
14667 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14668 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
14669 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
14671 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
14672 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14673 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14674 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
14676 IDirect3DSurface9_Release(original_ds);
14677 IDirect3DSurface9_Release(original_rt);
14678 IDirect3DSurface9_Release(readback);
14679 IDirect3DSurface9_Release(rt);
14680 refcount = IDirect3DDevice9_Release(device);
14681 ok(!refcount, "Device has %u references left.\n", refcount);
14682 done:
14683 IDirect3D9_Release(d3d);
14684 DestroyWindow(window);
14687 static void multisampled_depth_buffer_test(void)
14689 IDirect3DDevice9 *device = 0;
14690 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
14691 IDirect3D9 *d3d;
14692 D3DCAPS9 caps;
14693 HRESULT hr;
14694 D3DPRESENT_PARAMETERS present_parameters;
14695 unsigned int i;
14696 static const struct
14698 float x, y, z;
14699 D3DCOLOR color;
14701 quad_1[] =
14703 { -1.0f, 1.0f, 0.0f, 0xffff0000},
14704 { 1.0f, 1.0f, 1.0f, 0xffff0000},
14705 { -1.0f, -1.0f, 0.0f, 0xffff0000},
14706 { 1.0f, -1.0f, 1.0f, 0xffff0000},
14708 quad_2[] =
14710 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
14711 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
14712 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
14713 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
14715 static const struct
14717 UINT x, y;
14718 D3DCOLOR color;
14720 expected_colors[] =
14722 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14723 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14724 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14725 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14726 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14727 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14728 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14729 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14732 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14733 ok(!!d3d, "Failed to create a D3D object.\n");
14735 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14736 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14738 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
14739 IDirect3D9_Release(d3d);
14740 return;
14742 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14743 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14745 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
14746 IDirect3D9_Release(d3d);
14747 return;
14750 ZeroMemory(&present_parameters, sizeof(present_parameters));
14751 present_parameters.Windowed = TRUE;
14752 present_parameters.hDeviceWindow = create_window();
14753 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14754 present_parameters.BackBufferWidth = 640;
14755 present_parameters.BackBufferHeight = 480;
14756 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14757 present_parameters.EnableAutoDepthStencil = TRUE;
14758 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14759 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
14761 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14762 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
14763 &present_parameters, &device);
14764 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14766 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14767 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14768 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14770 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
14771 goto cleanup;
14774 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14775 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14776 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14777 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14778 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14779 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14781 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14782 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14783 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
14784 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14787 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14789 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14791 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14793 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14794 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14795 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14797 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14798 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14800 /* Render onscreen and then offscreen */
14801 hr = IDirect3DDevice9_BeginScene(device);
14802 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14804 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14805 hr = IDirect3DDevice9_EndScene(device);
14806 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14808 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
14809 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14810 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14811 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14813 hr = IDirect3DDevice9_BeginScene(device);
14814 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14816 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14817 hr = IDirect3DDevice9_EndScene(device);
14818 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14820 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
14821 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14823 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14825 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14826 ok(color_match(color, expected_colors[i].color, 1),
14827 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14828 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14831 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14832 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14834 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14836 /* Render offscreen and then onscreen */
14837 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14838 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14839 IDirect3DSurface9_Release(ds);
14840 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14841 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
14842 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14843 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14845 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14846 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14848 hr = IDirect3DDevice9_BeginScene(device);
14849 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14850 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14851 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14852 hr = IDirect3DDevice9_EndScene(device);
14853 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14855 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14856 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14857 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14858 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14860 hr = IDirect3DDevice9_BeginScene(device);
14861 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14863 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14864 hr = IDirect3DDevice9_EndScene(device);
14865 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14867 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
14868 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14870 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14872 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14873 ok(color_match(color, expected_colors[i].color, 1),
14874 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14875 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14879 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14881 IDirect3DSurface9_Release(ds);
14882 IDirect3DSurface9_Release(readback);
14883 IDirect3DSurface9_Release(rt);
14884 IDirect3DSurface9_Release(original_rt);
14885 cleanup_device(device);
14887 ZeroMemory(&present_parameters, sizeof(present_parameters));
14888 present_parameters.Windowed = TRUE;
14889 present_parameters.hDeviceWindow = create_window();
14890 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14891 present_parameters.BackBufferWidth = 640;
14892 present_parameters.BackBufferHeight = 480;
14893 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14894 present_parameters.EnableAutoDepthStencil = TRUE;
14895 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14896 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
14898 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14899 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
14900 &present_parameters, &device);
14901 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14903 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
14904 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
14906 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14907 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14908 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14909 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14910 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14911 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14912 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14913 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
14914 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14916 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14917 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14918 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14919 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14920 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14921 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14922 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14923 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14926 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14928 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14930 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14932 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14933 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14934 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14936 /* Render to a multisampled offscreen frame buffer and then blit to
14937 * the onscreen (not multisampled) frame buffer. */
14938 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14939 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14941 hr = IDirect3DDevice9_BeginScene(device);
14942 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14943 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14944 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14945 hr = IDirect3DDevice9_EndScene(device);
14946 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14948 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14949 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14950 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
14951 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14953 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14954 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14955 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
14956 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14958 hr = IDirect3DDevice9_BeginScene(device);
14959 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14961 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14962 hr = IDirect3DDevice9_EndScene(device);
14963 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14965 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
14966 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14968 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14970 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14971 ok(color_match(color, expected_colors[i].color, 1),
14972 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14973 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14977 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14979 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14980 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14981 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14982 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
14984 IDirect3DSurface9_Release(original_ds);
14985 IDirect3DSurface9_Release(original_rt);
14986 IDirect3DSurface9_Release(ds);
14987 IDirect3DSurface9_Release(readback);
14988 IDirect3DSurface9_Release(rt);
14989 cleanup:
14990 cleanup_device(device);
14991 IDirect3D9_Release(d3d);
14994 static void resz_test(void)
14996 IDirect3DDevice9 *device = 0;
14997 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
14998 D3DCAPS9 caps;
14999 HRESULT hr;
15000 D3DPRESENT_PARAMETERS present_parameters;
15001 unsigned int i;
15002 static const DWORD ps_code[] =
15004 0xffff0200, /* ps_2_0 */
15005 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15006 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15007 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
15008 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
15009 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15010 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
15011 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
15012 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
15013 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
15014 0x0000ffff, /* end */
15016 struct
15018 float x, y, z;
15019 float s, t, p, q;
15021 quad[] =
15023 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15024 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15025 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15026 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15028 struct
15030 UINT x, y;
15031 D3DCOLOR color;
15033 expected_colors[] =
15035 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15036 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15037 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15038 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15039 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15040 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15041 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15042 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15044 IDirect3DTexture9 *texture;
15045 IDirect3DPixelShader9 *ps;
15046 IDirect3D9 *d3d;
15047 DWORD value;
15049 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15050 ok(!!d3d, "Failed to create a D3D object.\n");
15052 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15053 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15055 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
15056 IDirect3D9_Release(d3d);
15057 return;
15059 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15060 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15062 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
15063 IDirect3D9_Release(d3d);
15064 return;
15067 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15068 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
15070 skip("No INTZ support, skipping RESZ test.\n");
15071 IDirect3D9_Release(d3d);
15072 return;
15075 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15076 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
15078 skip("No RESZ support, skipping RESZ test.\n");
15079 IDirect3D9_Release(d3d);
15080 return;
15083 ZeroMemory(&present_parameters, sizeof(present_parameters));
15084 present_parameters.Windowed = TRUE;
15085 present_parameters.hDeviceWindow = create_window();
15086 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15087 present_parameters.BackBufferWidth = 640;
15088 present_parameters.BackBufferHeight = 480;
15089 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15090 present_parameters.EnableAutoDepthStencil = FALSE;
15091 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15092 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15094 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15095 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15096 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15098 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15099 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15100 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15102 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
15103 cleanup_device(device);
15104 IDirect3D9_Release(d3d);
15105 return;
15107 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15109 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
15110 cleanup_device(device);
15111 IDirect3D9_Release(d3d);
15112 return;
15115 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15116 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15118 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15119 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15120 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15121 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15122 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15123 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15124 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15125 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15127 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15128 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15129 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15130 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15131 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15132 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15133 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15135 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15136 IDirect3DSurface9_Release(intz_ds);
15137 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15138 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15140 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15141 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15143 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15145 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15147 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15149 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15152 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15153 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15154 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15155 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15156 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15157 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15158 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15159 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15160 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15162 /* Render offscreen (multisampled), blit the depth buffer
15163 * into the INTZ texture and then check its contents */
15164 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15165 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15166 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15167 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15168 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15169 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15171 hr = IDirect3DDevice9_BeginScene(device);
15172 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15174 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15176 /* The destination depth texture has to be bound to sampler 0 */
15177 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15178 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15180 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
15181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15182 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15183 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15184 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15186 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15187 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15188 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15190 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15192 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15193 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15194 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15196 /* The actual multisampled depth buffer resolve happens here */
15197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15198 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15199 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15200 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15202 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15203 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15204 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15205 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15207 /* Read the depth values back */
15208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15209 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15210 hr = IDirect3DDevice9_EndScene(device);
15211 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15213 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15215 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15216 ok(color_match(color, expected_colors[i].color, 1),
15217 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15218 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15221 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15222 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15224 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15225 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15226 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15227 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15228 IDirect3DSurface9_Release(ds);
15229 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15230 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15231 IDirect3DTexture9_Release(texture);
15232 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15233 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15234 IDirect3DPixelShader9_Release(ps);
15235 IDirect3DSurface9_Release(readback);
15236 IDirect3DSurface9_Release(original_rt);
15237 IDirect3DSurface9_Release(rt);
15238 cleanup_device(device);
15241 ZeroMemory(&present_parameters, sizeof(present_parameters));
15242 present_parameters.Windowed = TRUE;
15243 present_parameters.hDeviceWindow = create_window();
15244 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15245 present_parameters.BackBufferWidth = 640;
15246 present_parameters.BackBufferHeight = 480;
15247 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15248 present_parameters.EnableAutoDepthStencil = TRUE;
15249 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15250 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15252 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15253 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15254 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15256 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15257 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15258 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15259 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15260 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15261 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15262 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15263 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15264 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15265 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15266 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15267 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15268 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15269 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15270 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15271 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15272 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15273 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15274 IDirect3DSurface9_Release(intz_ds);
15275 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15276 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15278 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15279 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15281 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15283 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15285 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15287 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15289 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15290 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15291 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15292 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15293 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15294 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15295 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15296 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15297 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15298 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15300 /* Render onscreen, blit the depth buffer into the INTZ texture
15301 * and then check its contents */
15302 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15303 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15304 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15305 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15306 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15307 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15309 hr = IDirect3DDevice9_BeginScene(device);
15310 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15312 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15313 hr = IDirect3DDevice9_EndScene(device);
15314 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15316 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15317 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15320 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15322 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15324 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15326 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15328 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15330 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15332 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15334 /* The actual multisampled depth buffer resolve happens here */
15335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15336 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15337 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15338 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15340 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15341 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15342 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15343 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15345 /* Read the depth values back */
15346 hr = IDirect3DDevice9_BeginScene(device);
15347 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15349 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15350 hr = IDirect3DDevice9_EndScene(device);
15351 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15353 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15355 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15356 ok(color_match(color, expected_colors[i].color, 1),
15357 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15358 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15362 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15365 /* Test edge cases - try with no texture at all */
15366 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15367 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15368 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15369 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15371 hr = IDirect3DDevice9_BeginScene(device);
15372 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15374 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15375 hr = IDirect3DDevice9_EndScene(device);
15376 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15379 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15381 /* With a non-multisampled depth buffer */
15382 IDirect3DSurface9_Release(ds);
15383 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15384 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15386 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15387 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15388 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15389 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15390 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15391 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15393 hr = IDirect3DDevice9_BeginScene(device);
15394 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15396 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15398 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15399 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15402 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15404 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15406 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15408 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15410 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15412 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15414 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15415 hr = IDirect3DDevice9_EndScene(device);
15416 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15419 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15421 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15422 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15424 /* Read the depth values back. */
15425 hr = IDirect3DDevice9_BeginScene(device);
15426 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15428 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15429 hr = IDirect3DDevice9_EndScene(device);
15430 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15432 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15434 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15435 ok(color_match(color, expected_colors[i].color, 1),
15436 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15437 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15440 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15441 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15443 /* Without a current depth-stencil buffer set */
15444 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15445 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15446 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15447 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15449 hr = IDirect3DDevice9_BeginScene(device);
15450 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15452 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15453 hr = IDirect3DDevice9_EndScene(device);
15454 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15457 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15459 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15460 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15461 IDirect3DSurface9_Release(ds);
15462 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15463 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15464 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15465 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15466 IDirect3DTexture9_Release(texture);
15467 IDirect3DPixelShader9_Release(ps);
15468 IDirect3DSurface9_Release(readback);
15469 IDirect3DSurface9_Release(original_rt);
15470 cleanup_device(device);
15471 IDirect3D9_Release(d3d);
15474 static void zenable_test(void)
15476 static const struct
15478 struct vec4 position;
15479 D3DCOLOR diffuse;
15481 tquad[] =
15483 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
15484 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
15485 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
15486 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
15488 IDirect3DDevice9 *device;
15489 IDirect3D9 *d3d;
15490 D3DCOLOR color;
15491 ULONG refcount;
15492 D3DCAPS9 caps;
15493 HWND window;
15494 HRESULT hr;
15495 UINT x, y;
15496 UINT i, j;
15498 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15499 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15500 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15501 ok(!!d3d, "Failed to create a D3D object.\n");
15502 if (!(device = create_device(d3d, window, window, TRUE)))
15504 skip("Failed to create a D3D device, skipping tests.\n");
15505 goto done;
15508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15509 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
15510 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
15511 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15513 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
15514 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15515 hr = IDirect3DDevice9_BeginScene(device);
15516 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
15518 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15519 hr = IDirect3DDevice9_EndScene(device);
15520 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15522 for (i = 0; i < 4; ++i)
15524 for (j = 0; j < 4; ++j)
15526 x = 80 * ((2 * j) + 1);
15527 y = 60 * ((2 * i) + 1);
15528 color = getPixelColor(device, x, y);
15529 ok(color_match(color, 0x0000ff00, 1),
15530 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
15534 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15535 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15537 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15538 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15540 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
15541 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
15543 static const DWORD vs_code[] =
15545 0xfffe0101, /* vs_1_1 */
15546 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15547 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15548 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
15549 0x0000ffff
15551 static const DWORD ps_code[] =
15553 0xffff0101, /* ps_1_1 */
15554 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
15555 0x0000ffff /* end */
15557 static const struct vec3 quad[] =
15559 {-1.0f, -1.0f, -0.5f},
15560 {-1.0f, 1.0f, -0.5f},
15561 { 1.0f, -1.0f, 1.5f},
15562 { 1.0f, 1.0f, 1.5f},
15564 static const D3DCOLOR expected[] =
15566 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
15567 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
15568 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
15569 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
15571 /* The Windows 8 testbot (WARP) appears to not clip z for regular
15572 * vertices either. */
15573 static const D3DCOLOR expected_broken[] =
15575 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
15576 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
15577 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
15578 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
15581 IDirect3DVertexShader9 *vs;
15582 IDirect3DPixelShader9 *ps;
15584 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15585 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15586 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15587 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
15588 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15589 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15590 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15591 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15592 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15593 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15595 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
15596 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15597 hr = IDirect3DDevice9_BeginScene(device);
15598 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15600 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15601 hr = IDirect3DDevice9_EndScene(device);
15602 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15604 for (i = 0; i < 4; ++i)
15606 for (j = 0; j < 4; ++j)
15608 x = 80 * ((2 * j) + 1);
15609 y = 60 * ((2 * i) + 1);
15610 color = getPixelColor(device, x, y);
15611 ok(color_match(color, expected[i * 4 + j], 1)
15612 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
15613 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
15617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15618 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15620 IDirect3DPixelShader9_Release(ps);
15621 IDirect3DVertexShader9_Release(vs);
15624 refcount = IDirect3DDevice9_Release(device);
15625 ok(!refcount, "Device has %u references left.\n", refcount);
15626 done:
15627 IDirect3D9_Release(d3d);
15628 DestroyWindow(window);
15631 static void fog_special_test(void)
15633 static const struct
15635 struct vec3 position;
15636 D3DCOLOR diffuse;
15638 quad[] =
15640 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
15641 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
15642 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
15643 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
15645 static const struct
15647 DWORD vertexmode, tablemode;
15648 BOOL vs, ps;
15649 D3DCOLOR color_left, color_right;
15651 tests[] =
15653 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
15654 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
15655 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
15656 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
15658 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
15659 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
15660 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
15661 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
15663 static const DWORD pixel_shader_code[] =
15665 0xffff0101, /* ps_1_1 */
15666 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
15667 0x0000ffff
15669 static const DWORD vertex_shader_code[] =
15671 0xfffe0101, /* vs_1_1 */
15672 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15673 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
15674 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15675 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
15676 0x0000ffff
15678 static const D3DMATRIX identity =
15680 1.0f, 0.0f, 0.0f, 0.0f,
15681 0.0f, 1.0f, 0.0f, 0.0f,
15682 0.0f, 0.0f, 1.0f, 0.0f,
15683 0.0f, 0.0f, 0.0f, 1.0f,
15684 }}};
15685 union
15687 float f;
15688 DWORD d;
15689 } conv;
15690 DWORD color;
15691 HRESULT hr;
15692 unsigned int i;
15693 IDirect3DPixelShader9 *ps;
15694 IDirect3DVertexShader9 *vs;
15695 IDirect3DDevice9 *device;
15696 IDirect3D9 *d3d;
15697 ULONG refcount;
15698 D3DCAPS9 caps;
15699 HWND window;
15701 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15702 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15703 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15704 ok(!!d3d, "Failed to create a D3D object.\n");
15705 if (!(device = create_device(d3d, window, window, TRUE)))
15707 skip("Failed to create a D3D device, skipping tests.\n");
15708 goto done;
15711 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15712 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15713 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
15715 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
15716 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
15718 else
15720 skip("Vertex Shaders not supported, skipping some fog tests.\n");
15721 vs = NULL;
15723 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
15725 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
15726 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15728 else
15730 skip("Pixel Shaders not supported, skipping some fog tests.\n");
15731 ps = NULL;
15734 /* The table fog tests seem to depend on the projection matrix explicitly
15735 * being set to an identity matrix, even though that's the default.
15736 * (AMD Radeon HD 6310, Windows 7) */
15737 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
15738 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
15740 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15741 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15743 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
15744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
15745 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
15746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
15747 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
15749 conv.f = 0.5f;
15750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
15751 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
15752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
15753 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
15755 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
15757 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15758 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15760 if (!tests[i].vs)
15762 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15763 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15765 else if (vs)
15767 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15768 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15770 else
15772 continue;
15775 if (!tests[i].ps)
15777 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15778 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15780 else if (ps)
15782 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15783 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15785 else
15787 continue;
15790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
15791 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
15792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
15793 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
15795 hr = IDirect3DDevice9_BeginScene(device);
15796 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15798 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15799 hr = IDirect3DDevice9_EndScene(device);
15800 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15802 color = getPixelColor(device, 310, 240);
15803 ok(color_match(color, tests[i].color_left, 1),
15804 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
15805 color = getPixelColor(device, 330, 240);
15806 ok(color_match(color, tests[i].color_right, 1),
15807 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
15809 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15810 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15813 if (vs)
15814 IDirect3DVertexShader9_Release(vs);
15815 if (ps)
15816 IDirect3DPixelShader9_Release(ps);
15817 refcount = IDirect3DDevice9_Release(device);
15818 ok(!refcount, "Device has %u references left.\n", refcount);
15819 done:
15820 IDirect3D9_Release(d3d);
15821 DestroyWindow(window);
15824 static void volume_srgb_test(void)
15826 HRESULT hr;
15827 unsigned int i, j;
15828 IDirect3DVolumeTexture9 *tex1, *tex2;
15829 D3DPOOL pool;
15830 D3DLOCKED_BOX locked_box;
15831 IDirect3DDevice9 *device;
15832 IDirect3D9 *d3d;
15833 D3DCOLOR color;
15834 ULONG refcount;
15835 HWND window;
15837 static const struct
15839 BOOL srgb;
15840 DWORD color;
15842 tests[] =
15844 /* Try toggling on and off */
15845 { FALSE, 0x007f7f7f },
15846 { TRUE, 0x00363636 },
15847 { FALSE, 0x007f7f7f },
15849 static const struct
15851 struct vec3 pos;
15852 struct vec3 texcrd;
15854 quad[] =
15856 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15857 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15858 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15859 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15862 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15863 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15864 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15865 ok(!!d3d, "Failed to create a D3D object.\n");
15866 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15867 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
15869 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
15870 goto done;
15872 if (!(device = create_device(d3d, window, window, TRUE)))
15874 skip("Failed to create a D3D device, skipping tests.\n");
15875 goto done;
15878 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15879 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
15880 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15881 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
15882 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
15883 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
15884 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
15885 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
15887 for (i = 0; i < 2; i++)
15889 if (!i)
15890 pool = D3DPOOL_SYSTEMMEM;
15891 else
15892 pool = D3DPOOL_MANAGED;
15894 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
15895 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15896 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
15897 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15898 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
15899 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
15900 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15902 if (!i)
15904 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
15905 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
15906 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15907 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
15908 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
15909 IDirect3DVolumeTexture9_Release(tex1);
15911 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
15912 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15913 IDirect3DVolumeTexture9_Release(tex2);
15915 else
15917 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
15918 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15919 IDirect3DVolumeTexture9_Release(tex1);
15922 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
15924 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
15925 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
15927 hr = IDirect3DDevice9_BeginScene(device);
15928 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15930 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15931 hr = IDirect3DDevice9_EndScene(device);
15932 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15934 color = getPixelColor(device, 320, 240);
15935 ok(color_match(color, tests[j].color, 2),
15936 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
15938 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15939 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15943 refcount = IDirect3DDevice9_Release(device);
15944 ok(!refcount, "Device has %u references left.\n", refcount);
15945 done:
15946 IDirect3D9_Release(d3d);
15947 DestroyWindow(window);
15950 static void volume_dxt5_test(void)
15952 IDirect3DVolumeTexture9 *texture;
15953 IDirect3DDevice9 *device;
15954 D3DLOCKED_BOX box;
15955 IDirect3D9 *d3d;
15956 unsigned int i;
15957 ULONG refcount;
15958 DWORD color;
15959 HWND window;
15960 HRESULT hr;
15962 static const char texture_data[] =
15964 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
15965 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
15966 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
15967 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
15968 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
15970 static const struct
15972 struct vec3 position;
15973 struct vec3 texcrd;
15975 quads[] =
15977 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
15978 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
15979 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
15980 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
15982 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
15983 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
15984 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
15985 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
15987 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
15989 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15990 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15991 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15992 ok(!!d3d, "Failed to create a D3D object.\n");
15993 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15994 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
15996 skip("DXT5 volume textures are not supported, skipping test.\n");
15997 goto done;
15999 if (!(device = create_device(d3d, window, window, TRUE)))
16001 skip("Failed to create a D3D device, skipping tests.\n");
16002 goto done;
16005 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
16006 D3DPOOL_MANAGED, &texture, NULL);
16007 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16009 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16010 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16011 memcpy(box.pBits, texture_data, sizeof(texture_data));
16012 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16013 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16015 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16016 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16017 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16018 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16019 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16020 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16021 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16022 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16023 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16024 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16025 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16026 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
16028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16029 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16030 hr = IDirect3DDevice9_BeginScene(device);
16031 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16032 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16033 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16035 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16036 hr = IDirect3DDevice9_EndScene(device);
16037 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16039 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16040 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16041 for (i = 0; i < 4; i++)
16043 color = getPixelColor(device, 80 + 160 * i, 240);
16044 ok (color_match(color, expected_colors[i], 1),
16045 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
16048 IDirect3DVolumeTexture9_Release(texture);
16049 refcount = IDirect3DDevice9_Release(device);
16050 ok(!refcount, "Device has %u references left.\n", refcount);
16051 done:
16052 IDirect3D9_Release(d3d);
16053 DestroyWindow(window);
16056 static void volume_v16u16_test(void)
16058 IDirect3DVolumeTexture9 *texture;
16059 IDirect3DPixelShader9 *shader;
16060 IDirect3DDevice9 *device;
16061 D3DLOCKED_BOX box;
16062 IDirect3D9 *d3d;
16063 unsigned int i;
16064 ULONG refcount;
16065 D3DCAPS9 caps;
16066 SHORT *texel;
16067 DWORD color;
16068 HWND window;
16069 HRESULT hr;
16071 static const struct
16073 struct vec3 position;
16074 struct vec3 texcrd;
16076 quads[] =
16078 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16079 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16080 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16081 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16083 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16084 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16085 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16086 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16088 static const DWORD shader_code[] =
16090 0xffff0101, /* ps_1_1 */
16091 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
16092 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
16093 0x00000042, 0xb00f0000, /* tex t0 */
16094 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
16095 0x0000ffff /* end */
16098 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16099 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16100 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16101 ok(!!d3d, "Failed to create a D3D object.\n");
16102 if (!(device = create_device(d3d, window, window, TRUE)))
16104 skip("Failed to create a D3D device, skipping tests.\n");
16105 goto done;
16108 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16109 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16110 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
16112 skip("No ps_1_1 support, skipping tests.\n");
16113 IDirect3DDevice9_Release(device);
16114 goto done;
16116 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16117 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
16119 skip("Volume V16U16 textures are not supported, skipping test.\n");
16120 IDirect3DDevice9_Release(device);
16121 goto done;
16124 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16125 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16126 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
16127 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16128 hr = IDirect3DDevice9_SetPixelShader(device, shader);
16129 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16130 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16131 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
16133 for (i = 0; i < 2; i++)
16135 D3DPOOL pool;
16137 if (i)
16138 pool = D3DPOOL_SYSTEMMEM;
16139 else
16140 pool = D3DPOOL_MANAGED;
16142 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16143 pool, &texture, NULL);
16144 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16146 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
16147 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16149 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
16150 texel[0] = 32767;
16151 texel[1] = 32767;
16152 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
16153 texel[0] = -32768;
16154 texel[1] = 0;
16155 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
16156 texel[0] = -16384;
16157 texel[1] = 16384;
16158 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
16159 texel[0] = 0;
16160 texel[1] = 0;
16162 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
16163 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
16165 if (i)
16167 IDirect3DVolumeTexture9 *texture2;
16169 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
16170 D3DPOOL_DEFAULT, &texture2, NULL);
16171 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16173 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
16174 (IDirect3DBaseTexture9 *)texture2);
16175 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16177 IDirect3DVolumeTexture9_Release(texture);
16178 texture = texture2;
16181 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
16182 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16184 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16185 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16186 hr = IDirect3DDevice9_BeginScene(device);
16187 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16189 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16191 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16192 hr = IDirect3DDevice9_EndScene(device);
16193 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16195 color = getPixelColor(device, 120, 160);
16196 ok (color_match(color, 0x000080ff, 2),
16197 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
16198 color = getPixelColor(device, 120, 400);
16199 ok (color_match(color, 0x00ffffff, 2),
16200 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
16201 color = getPixelColor(device, 360, 160);
16202 ok (color_match(color, 0x007f7fff, 2),
16203 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
16204 color = getPixelColor(device, 360, 400);
16205 ok (color_match(color, 0x0040c0ff, 2),
16206 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
16208 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16209 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16211 IDirect3DVolumeTexture9_Release(texture);
16214 IDirect3DPixelShader9_Release(shader);
16215 refcount = IDirect3DDevice9_Release(device);
16216 ok(!refcount, "Device has %u references left.\n", refcount);
16217 done:
16218 IDirect3D9_Release(d3d);
16219 DestroyWindow(window);
16222 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
16224 HRESULT hr;
16225 static const struct
16227 struct vec3 position;
16228 struct vec2 texcoord;
16230 quad[] =
16232 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
16233 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
16234 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
16235 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
16238 hr = IDirect3DDevice9_BeginScene(device);
16239 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
16241 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16242 hr = IDirect3DDevice9_EndScene(device);
16243 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16246 static void add_dirty_rect_test(void)
16248 HRESULT hr;
16249 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
16250 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
16251 IDirect3DDevice9 *device;
16252 IDirect3D9 *d3d;
16253 unsigned int i;
16254 ULONG refcount;
16255 DWORD *texel;
16256 HWND window;
16257 D3DLOCKED_RECT locked_rect;
16258 static const RECT part_rect = {96, 96, 160, 160};
16259 DWORD color;
16261 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16262 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16263 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16264 ok(!!d3d, "Failed to create a D3D object.\n");
16265 if (!(device = create_device(d3d, window, window, TRUE)))
16267 skip("Failed to create a D3D device, skipping tests.\n");
16268 IDirect3D9_Release(d3d);
16269 DestroyWindow(window);
16270 return;
16273 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16274 D3DPOOL_DEFAULT, &tex_dst1, NULL);
16275 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16276 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16277 D3DPOOL_DEFAULT, &tex_dst2, NULL);
16278 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16279 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16280 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
16281 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16282 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16283 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
16284 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16285 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16286 D3DPOOL_MANAGED, &tex_managed, NULL);
16287 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16289 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
16290 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16291 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
16292 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16293 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
16294 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16295 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
16296 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16298 fill_surface(surface_src_red, 0x00ff0000, 0);
16299 fill_surface(surface_src_green, 0x0000ff00, 0);
16301 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
16302 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16303 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16304 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16305 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16306 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16308 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16309 (IDirect3DBaseTexture9 *)tex_dst1);
16310 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16312 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
16313 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
16314 (IDirect3DBaseTexture9 *)tex_dst2);
16315 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16316 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16317 (IDirect3DBaseTexture9 *)tex_dst2);
16318 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16320 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
16321 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16322 add_dirty_rect_test_draw(device);
16323 color = getPixelColor(device, 320, 240);
16324 ok(color_match(color, 0x0000ff00, 1),
16325 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16326 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16327 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16329 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
16330 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16331 add_dirty_rect_test_draw(device);
16332 color = getPixelColor(device, 320, 240);
16333 todo_wine ok(color_match(color, 0x00ff0000, 1),
16334 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16336 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16338 /* AddDirtyRect on the destination is ignored. */
16339 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
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 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
16352 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16353 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16354 (IDirect3DBaseTexture9 *)tex_dst2);
16355 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16356 add_dirty_rect_test_draw(device);
16357 color = getPixelColor(device, 320, 240);
16358 todo_wine ok(color_match(color, 0x00ff0000, 1),
16359 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16360 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16361 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16363 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
16364 * tracking is supported. */
16365 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
16366 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16367 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16368 (IDirect3DBaseTexture9 *)tex_dst2);
16369 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16370 add_dirty_rect_test_draw(device);
16371 color = getPixelColor(device, 320, 240);
16372 ok(color_match(color, 0x0000ff00, 1),
16373 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16374 color = getPixelColor(device, 1, 1);
16375 todo_wine ok(color_match(color, 0x00ff0000, 1),
16376 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16377 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16378 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16380 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
16381 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16382 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16383 (IDirect3DBaseTexture9 *)tex_dst2);
16384 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16385 add_dirty_rect_test_draw(device);
16386 color = getPixelColor(device, 1, 1);
16387 ok(color_match(color, 0x0000ff00, 1),
16388 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16390 /* Locks with NO_DIRTY_UPDATE are ignored. */
16391 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
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 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
16403 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
16404 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16405 (IDirect3DBaseTexture9 *)tex_dst2);
16406 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16407 add_dirty_rect_test_draw(device);
16408 color = getPixelColor(device, 320, 240);
16409 todo_wine ok(color_match(color, 0x0000ff00, 1),
16410 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16411 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16412 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16414 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
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, 0x000000ff, 1),
16421 "Expected color 0x000000ff, 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 /* Maps without either of these flags record a dirty rectangle. */
16426 fill_surface(surface_src_green, 0x00ffffff, 0);
16427 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16428 (IDirect3DBaseTexture9 *)tex_dst2);
16429 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16430 add_dirty_rect_test_draw(device);
16431 color = getPixelColor(device, 320, 240);
16432 ok(color_match(color, 0x00ffffff, 1),
16433 "Expected color 0x00ffffff, got 0x%08x.\n", color);
16434 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16435 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16437 /* Partial LockRect works just like a partial AddDirtyRect call. */
16438 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
16439 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16440 texel = locked_rect.pBits;
16441 for (i = 0; i < 64; i++)
16442 texel[i] = 0x00ff00ff;
16443 for (i = 1; i < 64; i++)
16444 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
16445 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
16446 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16447 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16448 (IDirect3DBaseTexture9 *)tex_dst2);
16449 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16450 add_dirty_rect_test_draw(device);
16451 color = getPixelColor(device, 320, 240);
16452 ok(color_match(color, 0x00ff00ff, 1),
16453 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
16454 color = getPixelColor(device, 1, 1);
16455 ok(color_match(color, 0x00ffffff, 1),
16456 "Expected color 0x00ffffff, got 0x%08x.\n", color);
16457 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16458 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16460 fill_surface(surface_src_red, 0x00ff0000, 0);
16461 fill_surface(surface_src_green, 0x0000ff00, 0);
16463 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16464 (IDirect3DBaseTexture9 *)tex_dst1);
16465 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16466 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
16467 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16468 add_dirty_rect_test_draw(device);
16469 color = getPixelColor(device, 320, 240);
16470 ok(color_match(color, 0x0000ff00, 1),
16471 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16472 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16473 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16475 /* UpdateSurface ignores the missing dirty marker. */
16476 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
16477 (IDirect3DBaseTexture9 *)tex_dst2);
16478 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
16479 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
16480 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
16481 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16482 add_dirty_rect_test_draw(device);
16483 color = getPixelColor(device, 320, 240);
16484 ok(color_match(color, 0x0000ff00, 1),
16485 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16486 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16487 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16489 fill_surface(surface_managed, 0x00ff0000, 0);
16490 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
16491 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16492 add_dirty_rect_test_draw(device);
16493 color = getPixelColor(device, 320, 240);
16494 ok(color_match(color, 0x00ff0000, 1),
16495 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16496 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16497 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16499 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
16500 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
16501 add_dirty_rect_test_draw(device);
16502 color = getPixelColor(device, 320, 240);
16503 ok(color_match(color, 0x00ff0000, 1),
16504 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16505 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16506 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16508 /* AddDirtyRect uploads the new contents.
16509 * Side note, not tested in the test: Partial surface updates work, and two separate
16510 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
16511 * untested. */
16512 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16513 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16514 add_dirty_rect_test_draw(device);
16515 color = getPixelColor(device, 320, 240);
16516 ok(color_match(color, 0x0000ff00, 1),
16517 "Expected color 0x0000ff00, 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 /* So does EvictManagedResources. */
16522 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
16523 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16524 hr = IDirect3DDevice9_EvictManagedResources(device);
16525 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
16526 add_dirty_rect_test_draw(device);
16527 color = getPixelColor(device, 320, 240);
16528 ok(color_match(color, 0x000000ff, 1),
16529 "Expected color 0x000000ff, got 0x%08x.\n", color);
16530 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16531 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16533 /* AddDirtyRect on a locked texture is allowed. */
16534 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
16535 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16536 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
16537 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16538 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
16539 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16541 /* Redundant AddDirtyRect calls are ok. */
16542 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16543 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16544 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16545 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16547 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
16548 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16549 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16550 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16551 IDirect3DSurface9_Release(surface_dst2);
16552 IDirect3DSurface9_Release(surface_managed);
16553 IDirect3DSurface9_Release(surface_src_red);
16554 IDirect3DSurface9_Release(surface_src_green);
16555 IDirect3DTexture9_Release(tex_src_red);
16556 IDirect3DTexture9_Release(tex_src_green);
16557 IDirect3DTexture9_Release(tex_dst1);
16558 IDirect3DTexture9_Release(tex_dst2);
16559 IDirect3DTexture9_Release(tex_managed);
16560 refcount = IDirect3DDevice9_Release(device);
16561 ok(!refcount, "Device has %u references left.\n", refcount);
16562 IDirect3D9_Release(d3d);
16563 DestroyWindow(window);
16566 START_TEST(visual)
16568 IDirect3DDevice9 *device_ptr;
16569 D3DCAPS9 caps;
16570 HRESULT hr;
16571 DWORD color;
16573 if (!(device_ptr = init_d3d9()))
16575 skip("Creating the device failed\n");
16576 return;
16579 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
16581 /* Check for the reliability of the returned data */
16582 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
16583 if(FAILED(hr))
16585 skip("Clear failed, can't assure correctness of the test results, skipping\n");
16586 goto cleanup;
16589 color = getPixelColor(device_ptr, 1, 1);
16590 if(color !=0x00ff0000)
16592 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
16593 goto cleanup;
16595 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
16597 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
16598 if(FAILED(hr))
16600 skip("Clear failed, can't assure correctness of the test results, skipping\n");
16601 goto cleanup;
16604 color = getPixelColor(device_ptr, 639, 479);
16605 if(color != 0x0000ddee)
16607 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
16608 goto cleanup;
16610 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
16612 /* Now execute the real tests */
16613 depth_clamp_test(device_ptr);
16614 stretchrect_test(device_ptr);
16615 lighting_test(device_ptr);
16616 clear_test(device_ptr);
16617 color_fill_test(device_ptr);
16618 fog_test(device_ptr);
16619 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
16621 test_cube_wrap(device_ptr);
16622 } else {
16623 skip("No cube texture support\n");
16625 z_range_test(device_ptr);
16626 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
16628 maxmip_test(device_ptr);
16630 else
16632 skip("No mipmap support\n");
16635 offscreen_test(device_ptr);
16636 ds_size_test(device_ptr);
16637 alpha_test(device_ptr);
16638 shademode_test(device_ptr);
16639 srgbtexture_test(device_ptr);
16641 cleanup_device(device_ptr);
16642 device_ptr = NULL;
16644 release_buffer_test();
16645 float_texture_test();
16646 g16r16_texture_test();
16647 pixelshader_blending_test();
16648 texture_transform_flags_test();
16649 autogen_mipmap_test();
16650 fixed_function_decl_test();
16651 conditional_np2_repeat_test();
16652 fixed_function_bumpmap_test();
16653 pointsize_test();
16654 tssargtemp_test();
16655 np2_stretch_rect_test();
16656 yuv_color_test();
16657 yuv_layout_test();
16658 zwriteenable_test();
16659 alphatest_test();
16660 viewport_test();
16661 test_constant_clamp_vs();
16662 test_compare_instructions();
16663 test_mova();
16664 loop_index_test();
16665 sincos_test();
16666 sgn_test();
16667 clip_planes_test();
16668 test_vshader_input();
16669 test_vshader_float16();
16670 stream_test();
16671 fog_with_shader_test();
16672 texbem_test();
16673 texdepth_test();
16674 texkill_test();
16675 x8l8v8u8_test();
16676 volume_v16u16_test();
16677 constant_clamp_ps_test();
16678 cnd_test();
16679 dp2add_ps_test();
16680 unbound_sampler_test();
16681 nested_loop_test();
16682 pretransformed_varying_test();
16683 vface_register_test();
16684 vpos_register_test();
16685 multiple_rendertargets_test();
16686 texop_test();
16687 texop_range_test();
16688 alphareplicate_test();
16689 dp3_alpha_test();
16690 depth_buffer_test();
16691 depth_buffer2_test();
16692 depth_blit_test();
16693 intz_test();
16694 shadow_test();
16695 fp_special_test();
16696 depth_bounds_test();
16697 srgbwrite_format_test();
16698 update_surface_test();
16699 multisample_get_rtdata_test();
16700 zenable_test();
16701 fog_special_test();
16702 volume_srgb_test();
16703 volume_dxt5_test();
16704 add_dirty_rect_test();
16705 multisampled_depth_buffer_test();
16706 resz_test();
16707 stencil_cull_test();
16709 cleanup:
16710 cleanup_device(device_ptr);