d3d9/tests: Use a separate device for zwriteenable_test().
[wine.git] / dlls / d3d9 / tests / visual.c
blob0aad231ad71518a4c02bd5dc8b855ea348bd5188
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(IDirect3DDevice9 *device)
3711 IDirect3DVertexBuffer9 *vb = NULL;
3712 IDirect3DIndexBuffer9 *ib = NULL;
3713 HRESULT hr;
3714 BYTE *data;
3715 LONG ref;
3717 static const struct vertex quad[] = {
3718 {-1.0, -1.0, 0.1, 0xffff0000},
3719 {-1.0, 1.0, 0.1, 0xffff0000},
3720 { 1.0, 1.0, 0.1, 0xffff0000},
3722 {-1.0, -1.0, 0.1, 0xff00ff00},
3723 {-1.0, 1.0, 0.1, 0xff00ff00},
3724 { 1.0, 1.0, 0.1, 0xff00ff00}
3726 short indices[] = {3, 4, 5};
3728 /* Index and vertex buffers should always be creatable */
3729 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3730 D3DPOOL_MANAGED, &vb, NULL);
3731 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3732 if(!vb) {
3733 skip("Failed to create a vertex buffer\n");
3734 return;
3736 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3737 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3738 if(!ib) {
3739 skip("Failed to create an index buffer\n");
3740 return;
3743 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3744 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3745 memcpy(data, quad, sizeof(quad));
3746 hr = IDirect3DVertexBuffer9_Unlock(vb);
3747 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3749 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3750 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3751 memcpy(data, indices, sizeof(indices));
3752 hr = IDirect3DIndexBuffer9_Unlock(ib);
3753 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3755 hr = IDirect3DDevice9_SetIndices(device, ib);
3756 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3757 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3758 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3759 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3762 /* Now destroy the bound index buffer and draw again */
3763 ref = IDirect3DIndexBuffer9_Release(ib);
3764 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3769 hr = IDirect3DDevice9_BeginScene(device);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3771 if(SUCCEEDED(hr))
3773 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3774 * making assumptions about the indices or vertices
3776 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3778 hr = IDirect3DDevice9_EndScene(device);
3779 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3782 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3783 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3785 hr = IDirect3DDevice9_SetIndices(device, NULL);
3786 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3787 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3788 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3790 /* Index buffer was already destroyed as part of the test */
3791 IDirect3DVertexBuffer9_Release(vb);
3794 static void float_texture_test(IDirect3DDevice9 *device)
3796 IDirect3D9 *d3d = NULL;
3797 HRESULT hr;
3798 IDirect3DTexture9 *texture = NULL;
3799 D3DLOCKED_RECT lr;
3800 float *data;
3801 DWORD color;
3802 float quad[] = {
3803 -1.0, -1.0, 0.1, 0.0, 0.0,
3804 -1.0, 1.0, 0.1, 0.0, 1.0,
3805 1.0, -1.0, 0.1, 1.0, 0.0,
3806 1.0, 1.0, 0.1, 1.0, 1.0,
3809 memset(&lr, 0, sizeof(lr));
3810 IDirect3DDevice9_GetDirect3D(device, &d3d);
3811 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3812 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3813 skip("D3DFMT_R32F textures not supported\n");
3814 goto out;
3817 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3818 D3DPOOL_MANAGED, &texture, NULL);
3819 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3820 if(!texture) {
3821 skip("Failed to create R32F texture\n");
3822 goto out;
3825 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3826 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3827 data = lr.pBits;
3828 *data = 0.0;
3829 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3830 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3832 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3833 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3835 hr = IDirect3DDevice9_BeginScene(device);
3836 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3837 if(SUCCEEDED(hr))
3839 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3840 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3842 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3843 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3845 hr = IDirect3DDevice9_EndScene(device);
3846 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3848 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3849 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3851 color = getPixelColor(device, 240, 320);
3852 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
3854 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3855 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3857 out:
3858 if(texture) IDirect3DTexture9_Release(texture);
3859 IDirect3D9_Release(d3d);
3862 static void g16r16_texture_test(IDirect3DDevice9 *device)
3864 IDirect3D9 *d3d = NULL;
3865 HRESULT hr;
3866 IDirect3DTexture9 *texture = NULL;
3867 D3DLOCKED_RECT lr;
3868 DWORD *data;
3869 DWORD color;
3870 float quad[] = {
3871 -1.0, -1.0, 0.1, 0.0, 0.0,
3872 -1.0, 1.0, 0.1, 0.0, 1.0,
3873 1.0, -1.0, 0.1, 1.0, 0.0,
3874 1.0, 1.0, 0.1, 1.0, 1.0,
3877 memset(&lr, 0, sizeof(lr));
3878 IDirect3DDevice9_GetDirect3D(device, &d3d);
3879 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3880 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3881 skip("D3DFMT_G16R16 textures not supported\n");
3882 goto out;
3885 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3886 D3DPOOL_MANAGED, &texture, NULL);
3887 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3888 if(!texture) {
3889 skip("Failed to create D3DFMT_G16R16 texture\n");
3890 goto out;
3893 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3894 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3895 data = lr.pBits;
3896 *data = 0x0f00f000;
3897 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3898 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3900 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3901 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3903 hr = IDirect3DDevice9_BeginScene(device);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3905 if(SUCCEEDED(hr))
3907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3908 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3911 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3913 hr = IDirect3DDevice9_EndScene(device);
3914 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3916 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3917 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3919 color = getPixelColor(device, 240, 320);
3920 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3921 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3923 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3924 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3926 out:
3927 if(texture) IDirect3DTexture9_Release(texture);
3928 IDirect3D9_Release(d3d);
3931 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
3933 LONG x_coords[2][2] =
3935 {r.left - 1, r.left + 1},
3936 {r.right + 1, r.right - 1},
3938 LONG y_coords[2][2] =
3940 {r.top - 1, r.top + 1},
3941 {r.bottom + 1, r.bottom - 1}
3943 unsigned int i, j, x_side, y_side;
3945 for (i = 0; i < 2; ++i)
3947 for (j = 0; j < 2; ++j)
3949 for (x_side = 0; x_side < 2; ++x_side)
3951 for (y_side = 0; y_side < 2; ++y_side)
3953 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
3954 DWORD color;
3955 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
3957 color = getPixelColor(device, x, y);
3958 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
3959 message, x, y, color, expected);
3966 struct projected_textures_test_run
3968 const char *message;
3969 DWORD flags;
3970 IDirect3DVertexDeclaration9 *decl;
3971 BOOL vs, ps;
3972 RECT rect;
3975 static void projected_textures_test(IDirect3DDevice9 *device,
3976 struct projected_textures_test_run tests[4])
3978 unsigned int i;
3980 static const DWORD vertex_shader[] =
3982 0xfffe0101, /* vs_1_1 */
3983 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3984 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
3985 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3986 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
3987 0x0000ffff /* end */
3989 static const DWORD pixel_shader[] =
3991 0xffff0103, /* ps_1_3 */
3992 0x00000042, 0xb00f0000, /* tex t0 */
3993 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3994 0x0000ffff /* end */
3996 IDirect3DVertexShader9 *vs = NULL;
3997 IDirect3DPixelShader9 *ps = NULL;
3998 IDirect3D9 *d3d;
3999 D3DCAPS9 caps;
4000 HRESULT hr;
4002 IDirect3DDevice9_GetDirect3D(device, &d3d);
4003 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4004 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4005 IDirect3D9_Release(d3d);
4007 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4009 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4010 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4012 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4014 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4015 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4019 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4021 hr = IDirect3DDevice9_BeginScene(device);
4022 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4023 if (FAILED(hr))
4024 return;
4026 for (i = 0; i < 4; ++i)
4028 DWORD value = 0xdeadbeef;
4029 static const float proj_quads[] =
4031 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4032 0.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4033 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4034 0.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4036 0.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4037 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4038 0.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4039 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4041 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4042 0.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4043 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4044 0.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4046 0.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
4047 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
4048 0.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
4049 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
4052 if (tests[i].vs)
4054 if (!vs)
4056 skip("Vertex shaders not supported, skipping\n");
4057 continue;
4059 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4061 else
4062 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4063 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4064 if (tests[i].ps)
4066 if (!ps)
4068 skip("Pixel shaders not supported, skipping\n");
4069 continue;
4071 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4073 else
4074 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4075 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4077 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4078 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4080 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4081 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4082 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4083 ok(SUCCEEDED(hr) && value == tests[i].flags,
4084 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4087 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4088 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4091 hr = IDirect3DDevice9_EndScene(device);
4092 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4094 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4095 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4096 if (vs) IDirect3DVertexShader9_Release(vs);
4097 if (ps) IDirect3DPixelShader9_Release(ps);
4099 for (i = 0; i < 4; ++i)
4101 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4102 check_rect(device, tests[i].rect, tests[i].message);
4105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4106 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4109 static void texture_transform_flags_test(IDirect3DDevice9 *device)
4111 HRESULT hr;
4112 IDirect3D9 *d3d;
4113 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4114 D3DCAPS9 caps;
4115 IDirect3DTexture9 *texture = NULL;
4116 IDirect3DVolumeTexture9 *volume = NULL;
4117 unsigned int x, y, z;
4118 D3DLOCKED_RECT lr;
4119 D3DLOCKED_BOX lb;
4120 DWORD color;
4121 UINT w, h;
4122 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4123 float identity[16] = {1.0, 0.0, 0.0, 0.0,
4124 0.0, 1.0, 0.0, 0.0,
4125 0.0, 0.0, 1.0, 0.0,
4126 0.0, 0.0, 0.0, 1.0};
4127 static const D3DVERTEXELEMENT9 decl_elements[] = {
4128 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4129 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4130 D3DDECL_END()
4132 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4133 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4134 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4135 D3DDECL_END()
4137 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4138 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4139 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4140 D3DDECL_END()
4142 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4143 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4144 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4145 D3DDECL_END()
4147 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4148 0x00, 0xff, 0x00, 0x00,
4149 0x00, 0x00, 0x00, 0x00,
4150 0x00, 0x00, 0x00, 0x00};
4152 memset(&lr, 0, sizeof(lr));
4153 memset(&lb, 0, sizeof(lb));
4154 IDirect3DDevice9_GetDirect3D(device, &d3d);
4155 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
4156 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
4157 fmt = D3DFMT_A16B16G16R16;
4159 IDirect3D9_Release(d3d);
4161 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4163 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4164 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4165 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4167 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4168 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4169 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4170 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4171 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4172 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4173 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4174 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4175 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4176 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4177 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4178 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4179 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4180 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4181 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4182 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4183 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4184 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4185 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4186 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4187 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4188 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4190 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4192 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4193 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4194 w = min(1024, caps.MaxTextureWidth);
4195 h = min(1024, caps.MaxTextureHeight);
4196 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4197 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4198 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4199 if(!texture) {
4200 skip("Failed to create the test texture\n");
4201 return;
4204 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4205 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4206 * 1.0 in red and green for the x and y coords
4208 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4209 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4210 for(y = 0; y < h; y++) {
4211 for(x = 0; x < w; x++) {
4212 double r_f = (double) y / (double) h;
4213 double g_f = (double) x / (double) w;
4214 if(fmt == D3DFMT_A16B16G16R16) {
4215 unsigned short r, g;
4216 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4217 r = (unsigned short) (r_f * 65536.0);
4218 g = (unsigned short) (g_f * 65536.0);
4219 dst[0] = r;
4220 dst[1] = g;
4221 dst[2] = 0;
4222 dst[3] = 65535;
4223 } else {
4224 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4225 unsigned char r = (unsigned char) (r_f * 255.0);
4226 unsigned char g = (unsigned char) (g_f * 255.0);
4227 dst[0] = 0;
4228 dst[1] = g;
4229 dst[2] = r;
4230 dst[3] = 255;
4234 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4235 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4236 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4237 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4239 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4240 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4241 hr = IDirect3DDevice9_BeginScene(device);
4242 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4243 if(SUCCEEDED(hr))
4245 float quad1[] = {
4246 -1.0, -1.0, 0.1, 1.0, 1.0,
4247 -1.0, 0.0, 0.1, 1.0, 1.0,
4248 0.0, -1.0, 0.1, 1.0, 1.0,
4249 0.0, 0.0, 0.1, 1.0, 1.0,
4251 float quad2[] = {
4252 -1.0, 0.0, 0.1, 1.0, 1.0,
4253 -1.0, 1.0, 0.1, 1.0, 1.0,
4254 0.0, 0.0, 0.1, 1.0, 1.0,
4255 0.0, 1.0, 0.1, 1.0, 1.0,
4257 float quad3[] = {
4258 0.0, 0.0, 0.1, 0.5, 0.5,
4259 0.0, 1.0, 0.1, 0.5, 0.5,
4260 1.0, 0.0, 0.1, 0.5, 0.5,
4261 1.0, 1.0, 0.1, 0.5, 0.5,
4263 float quad4[] = {
4264 320, 480, 0.1, 1.0, 0.0, 1.0,
4265 320, 240, 0.1, 1.0, 0.0, 1.0,
4266 640, 480, 0.1, 1.0, 0.0, 1.0,
4267 640, 240, 0.1, 1.0, 0.0, 1.0,
4269 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4270 0.0, 0.0, 0.0, 0.0,
4271 0.0, 0.0, 0.0, 0.0,
4272 0.0, 0.0, 0.0, 0.0};
4274 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4275 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4276 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4278 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4280 /* What happens with transforms enabled? */
4281 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4282 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4284 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4286 /* What happens if 4 coords are used, but only 2 given ?*/
4287 mat[8] = 1.0;
4288 mat[13] = 1.0;
4289 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4291 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4294 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4296 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4297 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4298 * due to the coords in the vertices. (turns out red, indeed)
4300 memset(mat, 0, sizeof(mat));
4301 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4302 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4303 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4304 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4305 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4306 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4308 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4310 hr = IDirect3DDevice9_EndScene(device);
4311 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4313 color = getPixelColor(device, 160, 360);
4314 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4315 color = getPixelColor(device, 160, 120);
4316 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4317 color = getPixelColor(device, 480, 120);
4318 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4319 color = getPixelColor(device, 480, 360);
4320 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4321 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4322 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4325 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4327 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4328 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4329 hr = IDirect3DDevice9_BeginScene(device);
4330 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4331 if(SUCCEEDED(hr))
4333 float quad1[] = {
4334 -1.0, -1.0, 0.1, 0.8, 0.2,
4335 -1.0, 0.0, 0.1, 0.8, 0.2,
4336 0.0, -1.0, 0.1, 0.8, 0.2,
4337 0.0, 0.0, 0.1, 0.8, 0.2,
4339 float quad2[] = {
4340 -1.0, 0.0, 0.1, 0.5, 1.0,
4341 -1.0, 1.0, 0.1, 0.5, 1.0,
4342 0.0, 0.0, 0.1, 0.5, 1.0,
4343 0.0, 1.0, 0.1, 0.5, 1.0,
4345 float quad3[] = {
4346 0.0, 0.0, 0.1, 0.5, 1.0,
4347 0.0, 1.0, 0.1, 0.5, 1.0,
4348 1.0, 0.0, 0.1, 0.5, 1.0,
4349 1.0, 1.0, 0.1, 0.5, 1.0,
4351 float quad4[] = {
4352 0.0, -1.0, 0.1, 0.8, 0.2,
4353 0.0, 0.0, 0.1, 0.8, 0.2,
4354 1.0, -1.0, 0.1, 0.8, 0.2,
4355 1.0, 0.0, 0.1, 0.8, 0.2,
4357 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4358 0.0, 0.0, 0.0, 0.0,
4359 0.0, 1.0, 0.0, 0.0,
4360 0.0, 0.0, 0.0, 0.0};
4362 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4363 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4364 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4365 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4366 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4369 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4371 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4372 * it behaves like COUNT2 because normal textures require 2 coords. */
4373 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4374 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4376 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4378 /* Just to be sure, the same as quad2 above */
4379 memset(mat, 0, sizeof(mat));
4380 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
4381 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4382 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4387 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4388 * used? And what happens to the first? */
4389 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4390 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4392 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4394 hr = IDirect3DDevice9_EndScene(device);
4395 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4397 color = getPixelColor(device, 160, 360);
4398 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4399 color = getPixelColor(device, 160, 120);
4400 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4401 color = getPixelColor(device, 480, 120);
4402 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4403 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4404 color = getPixelColor(device, 480, 360);
4405 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4406 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4410 IDirect3DTexture9_Release(texture);
4412 /* Test projected textures, without any fancy matrices */
4413 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4414 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4415 if (SUCCEEDED(hr))
4417 struct projected_textures_test_run projected_tests_1[4] =
4420 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4421 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4422 decl3,
4423 FALSE, TRUE,
4424 {120, 300, 240, 390},
4427 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4428 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4429 decl3,
4430 FALSE, TRUE,
4431 {400, 360, 480, 420},
4433 /* Try with some invalid values */
4435 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4436 0xffffffff,
4437 decl3,
4438 FALSE, TRUE,
4439 {120, 60, 240, 150}
4442 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4443 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4444 decl4,
4445 FALSE, TRUE,
4446 {340, 210, 360, 225},
4449 struct projected_textures_test_run projected_tests_2[4] =
4452 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4453 D3DTTFF_PROJECTED,
4454 decl3,
4455 FALSE, TRUE,
4456 {120, 300, 240, 390},
4459 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4460 D3DTTFF_PROJECTED,
4461 decl,
4462 FALSE, TRUE,
4463 {400, 360, 480, 420},
4466 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
4467 0xffffffff,
4468 decl,
4469 FALSE, TRUE,
4470 {80, 120, 160, 180},
4473 "D3DTTFF_COUNT1 (draws non-projected) - top right",
4474 D3DTTFF_COUNT1,
4475 decl4,
4476 FALSE, TRUE,
4477 {340, 210, 360, 225},
4480 struct projected_textures_test_run projected_tests_3[4] =
4483 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
4484 D3DTTFF_PROJECTED,
4485 decl3,
4486 TRUE, FALSE,
4487 {120, 300, 240, 390},
4490 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
4491 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4492 decl3,
4493 TRUE, TRUE,
4494 {440, 300, 560, 390},
4497 "0xffffffff (like COUNT4 | PROJECTED) - top left",
4498 0xffffffff,
4499 decl3,
4500 TRUE, TRUE,
4501 {120, 60, 240, 150},
4504 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
4505 D3DTTFF_PROJECTED,
4506 decl3,
4507 FALSE, FALSE,
4508 {440, 60, 560, 150},
4512 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4513 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4515 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4516 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4517 for(x = 0; x < 4; x++) {
4518 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
4520 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4521 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4522 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4523 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4525 projected_textures_test(device, projected_tests_1);
4526 projected_textures_test(device, projected_tests_2);
4527 projected_textures_test(device, projected_tests_3);
4529 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4531 IDirect3DTexture9_Release(texture);
4534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
4535 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4536 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
4537 * Thus watch out if sampling from texels between 0 and 1.
4539 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
4540 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
4541 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
4542 if(!volume) {
4543 skip("Failed to create a volume texture\n");
4544 goto out;
4547 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
4548 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
4549 for(z = 0; z < 32; z++) {
4550 for(y = 0; y < 32; y++) {
4551 for(x = 0; x < 32; x++) {
4552 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
4553 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
4554 float r_f = (float) x / 31.0;
4555 float g_f = (float) y / 31.0;
4556 float b_f = (float) z / 31.0;
4558 if(fmt == D3DFMT_A16B16G16R16) {
4559 unsigned short *mem_s = mem;
4560 mem_s[0] = r_f * 65535.0;
4561 mem_s[1] = g_f * 65535.0;
4562 mem_s[2] = b_f * 65535.0;
4563 mem_s[3] = 65535;
4564 } else {
4565 unsigned char *mem_c = mem;
4566 mem_c[0] = b_f * 255.0;
4567 mem_c[1] = g_f * 255.0;
4568 mem_c[2] = r_f * 255.0;
4569 mem_c[3] = 255;
4574 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
4575 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4577 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
4578 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
4580 hr = IDirect3DDevice9_BeginScene(device);
4581 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4582 if(SUCCEEDED(hr))
4584 float quad1[] = {
4585 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4586 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4587 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4588 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4590 float quad2[] = {
4591 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4592 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
4593 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4594 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
4596 float quad3[] = {
4597 0.0, 0.0, 0.1, 0.0, 0.0,
4598 0.0, 1.0, 0.1, 0.0, 0.0,
4599 1.0, 0.0, 0.1, 0.0, 0.0,
4600 1.0, 1.0, 0.1, 0.0, 0.0
4602 float quad4[] = {
4603 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4604 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4605 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4606 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
4608 float mat[16] = {1.0, 0.0, 0.0, 0.0,
4609 0.0, 0.0, 1.0, 0.0,
4610 0.0, 1.0, 0.0, 0.0,
4611 0.0, 0.0, 0.0, 1.0};
4612 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4613 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4615 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
4616 * values
4618 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4619 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4620 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4621 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4623 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4625 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
4626 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
4627 * otherwise the w will be missing(blue).
4628 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
4629 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
4630 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4631 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4633 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4635 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
4636 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4637 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4638 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4639 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4640 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4641 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4643 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4645 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4646 * disable. ATI extends it up to the amount of values needed for the volume texture
4648 memset(mat, 0, sizeof(mat));
4649 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4650 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4651 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4652 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4653 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4654 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4656 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4658 hr = IDirect3DDevice9_EndScene(device);
4659 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4662 color = getPixelColor(device, 160, 360);
4663 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4664 color = getPixelColor(device, 160, 120);
4665 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4666 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4667 color = getPixelColor(device, 480, 120);
4668 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4669 color = getPixelColor(device, 480, 360);
4670 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4672 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4673 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4676 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4677 hr = IDirect3DDevice9_BeginScene(device);
4678 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4679 if(SUCCEEDED(hr))
4681 float quad1[] = {
4682 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4683 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4684 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4685 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4687 float quad2[] = {
4688 -1.0, 0.0, 0.1,
4689 -1.0, 1.0, 0.1,
4690 0.0, 0.0, 0.1,
4691 0.0, 1.0, 0.1,
4693 float quad3[] = {
4694 0.0, 0.0, 0.1, 1.0,
4695 0.0, 1.0, 0.1, 1.0,
4696 1.0, 0.0, 0.1, 1.0,
4697 1.0, 1.0, 0.1, 1.0
4699 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4700 0.0, 0.0, 0.0, 0.0,
4701 0.0, 0.0, 0.0, 0.0,
4702 0.0, 1.0, 0.0, 0.0};
4703 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4704 1.0, 0.0, 0.0, 0.0,
4705 0.0, 1.0, 0.0, 0.0,
4706 0.0, 0.0, 1.0, 0.0};
4707 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4708 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4710 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4711 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4712 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4713 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4714 * 4th *input* coordinate.
4716 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4717 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4718 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4719 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4721 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4723 /* None passed */
4724 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4725 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4726 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4727 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4729 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4731 /* 4 used, 1 passed */
4732 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4733 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4734 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4735 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4737 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4739 hr = IDirect3DDevice9_EndScene(device);
4740 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4742 color = getPixelColor(device, 160, 360);
4743 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4744 color = getPixelColor(device, 160, 120);
4745 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4746 color = getPixelColor(device, 480, 120);
4747 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4748 /* Quad4: unused */
4750 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4753 IDirect3DVolumeTexture9_Release(volume);
4755 out:
4756 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4757 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4758 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4759 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4760 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4762 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4763 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4764 IDirect3DVertexDeclaration9_Release(decl);
4765 IDirect3DVertexDeclaration9_Release(decl2);
4766 IDirect3DVertexDeclaration9_Release(decl3);
4767 IDirect3DVertexDeclaration9_Release(decl4);
4770 static void texdepth_test(void)
4772 IDirect3DPixelShader9 *shader;
4773 IDirect3DDevice9 *device;
4774 IDirect3D9 *d3d;
4775 ULONG refcount;
4776 D3DCAPS9 caps;
4777 DWORD color;
4778 HWND window;
4779 HRESULT hr;
4781 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
4782 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
4783 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
4784 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
4785 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
4786 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
4787 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
4788 static const DWORD shader_code[] =
4790 0xffff0104, /* ps_1_4 */
4791 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4792 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4793 0x0000fffd, /* phase */
4794 0x00000057, 0x800f0005, /* texdepth r5 */
4795 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4796 0x0000ffff /* end */
4798 static const float vertex[] =
4800 -1.0f, -1.0f, 0.0f,
4801 -1.0f, 1.0f, 0.0f,
4802 1.0f, -1.0f, 1.0f,
4803 1.0f, 1.0f, 1.0f,
4806 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4807 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4808 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4809 ok(!!d3d, "Failed to create a D3D object.\n");
4810 if (!(device = create_device(d3d, window, window, TRUE)))
4812 skip("Failed to create a D3D device, skipping tests.\n");
4813 goto done;
4816 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4817 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4818 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4820 skip("No ps_1_1 support, skipping tests.\n");
4821 IDirect3DDevice9_Release(device);
4822 goto done;
4825 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4828 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4829 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4831 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4833 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4835 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4838 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4839 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4841 /* Fill the depth buffer with a gradient */
4842 hr = IDirect3DDevice9_BeginScene(device);
4843 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4844 if(SUCCEEDED(hr))
4846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4847 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4848 hr = IDirect3DDevice9_EndScene(device);
4849 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4852 /* Now perform the actual tests. Same geometry, but with the shader */
4853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4857 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4858 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4860 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4861 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4862 hr = IDirect3DDevice9_BeginScene(device);
4863 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4864 if(SUCCEEDED(hr))
4866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4867 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4869 hr = IDirect3DDevice9_EndScene(device);
4870 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4873 color = getPixelColor(device, 158, 240);
4874 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4875 color = getPixelColor(device, 162, 240);
4876 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4879 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4882 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4884 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4885 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4886 hr = IDirect3DDevice9_BeginScene(device);
4887 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4888 if(SUCCEEDED(hr))
4890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4891 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4893 hr = IDirect3DDevice9_EndScene(device);
4894 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4897 color = getPixelColor(device, 318, 240);
4898 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4899 color = getPixelColor(device, 322, 240);
4900 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4902 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4903 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4905 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4906 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4908 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4909 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4910 hr = IDirect3DDevice9_BeginScene(device);
4911 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4912 if(SUCCEEDED(hr))
4914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4915 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4917 hr = IDirect3DDevice9_EndScene(device);
4918 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4921 color = getPixelColor(device, 1, 240);
4922 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4924 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4925 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4928 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4930 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4931 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4932 hr = IDirect3DDevice9_BeginScene(device);
4933 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4934 if(SUCCEEDED(hr))
4936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4937 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4939 hr = IDirect3DDevice9_EndScene(device);
4940 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4942 color = getPixelColor(device, 318, 240);
4943 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4944 color = getPixelColor(device, 322, 240);
4945 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4947 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4951 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4953 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4954 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4955 hr = IDirect3DDevice9_BeginScene(device);
4956 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4957 if(SUCCEEDED(hr))
4959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4960 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4962 hr = IDirect3DDevice9_EndScene(device);
4963 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4966 color = getPixelColor(device, 1, 240);
4967 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4969 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4970 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4973 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4975 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4977 hr = IDirect3DDevice9_BeginScene(device);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4979 if(SUCCEEDED(hr))
4981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4982 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4984 hr = IDirect3DDevice9_EndScene(device);
4985 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4988 color = getPixelColor(device, 638, 240);
4989 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4994 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4995 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4997 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4998 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4999 hr = IDirect3DDevice9_BeginScene(device);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5001 if(SUCCEEDED(hr))
5003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5004 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5006 hr = IDirect3DDevice9_EndScene(device);
5007 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5010 color = getPixelColor(device, 638, 240);
5011 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5013 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5014 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5016 IDirect3DPixelShader9_Release(shader);
5017 refcount = IDirect3DDevice9_Release(device);
5018 ok(!refcount, "Device has %u references left.\n", refcount);
5019 done:
5020 IDirect3D9_Release(d3d);
5021 DestroyWindow(window);
5024 static void texkill_test(void)
5026 IDirect3DPixelShader9 *shader;
5027 IDirect3DDevice9 *device;
5028 IDirect3D9 *d3d;
5029 ULONG refcount;
5030 D3DCAPS9 caps;
5031 DWORD color;
5032 HWND window;
5033 HRESULT hr;
5035 static const float vertex[] =
5037 /* bottom top right left */
5038 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5039 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5040 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5041 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5043 static const DWORD shader_code_11[] =
5045 0xffff0101, /* ps_1_1 */
5046 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5047 0x00000041, 0xb00f0000, /* texkill t0 */
5048 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5049 0x0000ffff /* end */
5051 static const DWORD shader_code_20[] =
5053 0xffff0200, /* ps_2_0 */
5054 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5055 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5056 0x01000041, 0xb00f0000, /* texkill t0 */
5057 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5058 0x0000ffff /* end */
5061 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5062 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5063 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5064 ok(!!d3d, "Failed to create a D3D object.\n");
5065 if (!(device = create_device(d3d, window, window, TRUE)))
5067 skip("Failed to create a D3D device, skipping tests.\n");
5068 goto done;
5071 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5072 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5073 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5075 skip("No ps_1_1 support, skipping tests.\n");
5076 IDirect3DDevice9_Release(device);
5077 goto done;
5080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5081 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5082 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5083 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5085 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5086 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5087 hr = IDirect3DDevice9_BeginScene(device);
5088 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5089 if(SUCCEEDED(hr))
5091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5092 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5093 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5094 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5095 hr = IDirect3DDevice9_EndScene(device);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5098 color = getPixelColor(device, 63, 46);
5099 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5100 color = getPixelColor(device, 66, 46);
5101 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5102 color = getPixelColor(device, 63, 49);
5103 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5104 color = getPixelColor(device, 66, 49);
5105 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5107 color = getPixelColor(device, 578, 46);
5108 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5109 color = getPixelColor(device, 575, 46);
5110 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5111 color = getPixelColor(device, 578, 49);
5112 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5113 color = getPixelColor(device, 575, 49);
5114 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5116 color = getPixelColor(device, 63, 430);
5117 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5118 color = getPixelColor(device, 63, 433);
5119 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5120 color = getPixelColor(device, 66, 433);
5121 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5122 color = getPixelColor(device, 66, 430);
5123 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5125 color = getPixelColor(device, 578, 430);
5126 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5127 color = getPixelColor(device, 578, 433);
5128 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5129 color = getPixelColor(device, 575, 433);
5130 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5131 color = getPixelColor(device, 575, 430);
5132 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5134 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5135 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5137 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5138 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5139 IDirect3DPixelShader9_Release(shader);
5141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5142 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5143 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5145 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5146 IDirect3DDevice9_Release(device);
5147 goto done;
5150 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5151 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5152 hr = IDirect3DDevice9_BeginScene(device);
5153 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5154 if(SUCCEEDED(hr))
5156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5157 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5158 hr = IDirect3DDevice9_EndScene(device);
5159 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5162 color = getPixelColor(device, 63, 46);
5163 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5164 color = getPixelColor(device, 66, 46);
5165 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5166 color = getPixelColor(device, 63, 49);
5167 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5168 color = getPixelColor(device, 66, 49);
5169 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5171 color = getPixelColor(device, 578, 46);
5172 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5173 color = getPixelColor(device, 575, 46);
5174 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5175 color = getPixelColor(device, 578, 49);
5176 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5177 color = getPixelColor(device, 575, 49);
5178 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5180 color = getPixelColor(device, 63, 430);
5181 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5182 color = getPixelColor(device, 63, 433);
5183 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5184 color = getPixelColor(device, 66, 433);
5185 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5186 color = getPixelColor(device, 66, 430);
5187 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5189 color = getPixelColor(device, 578, 430);
5190 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5191 color = getPixelColor(device, 578, 433);
5192 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5193 color = getPixelColor(device, 575, 433);
5194 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5195 color = getPixelColor(device, 575, 430);
5196 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5198 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5199 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5201 IDirect3DPixelShader9_Release(shader);
5202 refcount = IDirect3DDevice9_Release(device);
5203 ok(!refcount, "Device has %u references left.\n", refcount);
5204 done:
5205 IDirect3D9_Release(d3d);
5206 DestroyWindow(window);
5209 static void x8l8v8u8_test(void)
5211 IDirect3DPixelShader9 *shader2;
5212 IDirect3DPixelShader9 *shader;
5213 IDirect3DTexture9 *texture;
5214 IDirect3DDevice9 *device;
5215 D3DLOCKED_RECT lr;
5216 IDirect3D9 *d3d;
5217 ULONG refcount;
5218 D3DCAPS9 caps;
5219 DWORD color;
5220 HWND window;
5221 HRESULT hr;
5223 static const DWORD shader_code[] =
5225 0xffff0101, /* ps_1_1 */
5226 0x00000042, 0xb00f0000, /* tex t0 */
5227 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5228 0x0000ffff /* end */
5230 static const DWORD shader_code2[] =
5232 0xffff0101, /* ps_1_1 */
5233 0x00000042, 0xb00f0000, /* tex t0 */
5234 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
5235 0x0000ffff /* end */
5237 static const float quad[] =
5239 -1.0f, -1.0f, 0.1f, 0.5f, 0.5f,
5240 -1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5241 1.0f, -1.0f, 0.1f, 0.5f, 0.5f,
5242 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5245 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5246 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5247 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5248 ok(!!d3d, "Failed to create a D3D object.\n");
5249 if (!(device = create_device(d3d, window, window, TRUE)))
5251 skip("Failed to create a D3D device, skipping tests.\n");
5252 goto done;
5255 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5256 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5257 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5259 skip("No ps_1_1 support, skipping tests.\n");
5260 IDirect3DDevice9_Release(device);
5261 goto done;
5263 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5264 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8)))
5266 skip("No D3DFMT_X8L8V8U8 support, skipping tests.\n");
5267 IDirect3DDevice9_Release(device);
5268 goto done;
5271 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
5272 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5274 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
5275 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
5276 memset(&lr, 0, sizeof(lr));
5277 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5278 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
5279 *((DWORD *) lr.pBits) = 0x11ca3141;
5280 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5281 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
5283 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5284 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5285 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
5288 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5289 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5290 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5291 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5292 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5293 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
5295 hr = IDirect3DDevice9_BeginScene(device);
5296 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5297 if(SUCCEEDED(hr))
5299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5300 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5302 hr = IDirect3DDevice9_EndScene(device);
5303 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5305 color = getPixelColor(device, 578, 430);
5306 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
5307 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
5308 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5309 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5311 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
5312 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5313 hr = IDirect3DDevice9_BeginScene(device);
5314 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5315 if(SUCCEEDED(hr))
5317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5318 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5320 hr = IDirect3DDevice9_EndScene(device);
5321 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5323 color = getPixelColor(device, 578, 430);
5324 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
5325 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5326 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5328 IDirect3DPixelShader9_Release(shader);
5329 IDirect3DPixelShader9_Release(shader2);
5330 IDirect3DTexture9_Release(texture);
5331 refcount = IDirect3DDevice9_Release(device);
5332 ok(!refcount, "Device has %u references left.\n", refcount);
5333 done:
5334 IDirect3D9_Release(d3d);
5335 DestroyWindow(window);
5338 static void autogen_mipmap_test(IDirect3DDevice9 *device)
5340 HRESULT hr;
5341 IDirect3D9 *d3d;
5342 IDirect3DTexture9 *texture = NULL;
5343 IDirect3DSurface9 *surface;
5344 DWORD color;
5345 const RECT r1 = {256, 256, 512, 512};
5346 const RECT r2 = {512, 256, 768, 512};
5347 const RECT r3 = {256, 512, 512, 768};
5348 const RECT r4 = {512, 512, 768, 768};
5349 unsigned int x, y;
5350 D3DLOCKED_RECT lr;
5351 memset(&lr, 0, sizeof(lr));
5353 IDirect3DDevice9_GetDirect3D(device, &d3d);
5354 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5355 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
5356 skip("No autogenmipmap support\n");
5357 IDirect3D9_Release(d3d);
5358 return;
5360 IDirect3D9_Release(d3d);
5362 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5363 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5365 /* Make the mipmap big, so that a smaller mipmap is used
5367 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5368 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5369 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5371 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5372 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5373 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5374 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5375 for(y = 0; y < 1024; y++) {
5376 for(x = 0; x < 1024; x++) {
5377 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5378 POINT pt;
5380 pt.x = x;
5381 pt.y = y;
5382 if(PtInRect(&r1, pt)) {
5383 *dst = 0xffff0000;
5384 } else if(PtInRect(&r2, pt)) {
5385 *dst = 0xff00ff00;
5386 } else if(PtInRect(&r3, pt)) {
5387 *dst = 0xff0000ff;
5388 } else if(PtInRect(&r4, pt)) {
5389 *dst = 0xff000000;
5390 } else {
5391 *dst = 0xffffffff;
5395 hr = IDirect3DSurface9_UnlockRect(surface);
5396 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5397 IDirect3DSurface9_Release(surface);
5399 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5400 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5401 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5402 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5404 hr = IDirect3DDevice9_BeginScene(device);
5405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5406 if(SUCCEEDED(hr)) {
5407 const float quad[] = {
5408 -0.5, -0.5, 0.1, 0.0, 0.0,
5409 -0.5, 0.5, 0.1, 0.0, 1.0,
5410 0.5, -0.5, 0.1, 1.0, 0.0,
5411 0.5, 0.5, 0.1, 1.0, 1.0
5414 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5415 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5416 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5417 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5418 hr = IDirect3DDevice9_EndScene(device);
5419 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5421 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5423 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5424 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5425 IDirect3DTexture9_Release(texture);
5427 color = getPixelColor(device, 200, 200);
5428 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5429 color = getPixelColor(device, 280, 200);
5430 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5431 color = getPixelColor(device, 360, 200);
5432 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5433 color = getPixelColor(device, 440, 200);
5434 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5435 color = getPixelColor(device, 200, 270);
5436 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5437 color = getPixelColor(device, 280, 270);
5438 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5439 color = getPixelColor(device, 360, 270);
5440 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5441 color = getPixelColor(device, 440, 270);
5442 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5443 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5444 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5447 static void test_constant_clamp_vs(void)
5449 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5450 IDirect3DVertexDeclaration9 *decl;
5451 IDirect3DDevice9 *device;
5452 IDirect3D9 *d3d;
5453 D3DCOLOR color;
5454 ULONG refcount;
5455 D3DCAPS9 caps;
5456 HWND window;
5457 HRESULT hr;
5459 static const DWORD shader_code_11[] =
5461 0xfffe0101, /* vs_1_1 */
5462 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5463 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5464 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5465 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5466 0x0000ffff /* end */
5468 static const DWORD shader_code_11_2[] =
5470 0xfffe0101, /* vs_1_1 */
5471 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5472 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5473 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5474 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5475 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5476 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5477 0x0000ffff /* end */
5479 static const DWORD shader_code_20[] =
5481 0xfffe0200, /* vs_2_0 */
5482 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5483 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5484 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5485 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5486 0x0000ffff /* end */
5488 static const DWORD shader_code_20_2[] =
5490 0xfffe0200, /* vs_2_0 */
5491 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5492 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5493 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5494 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5495 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5496 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5497 0x0000ffff /* end */
5499 static const D3DVERTEXELEMENT9 decl_elements[] =
5501 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5502 D3DDECL_END()
5504 static const float quad1[] =
5506 -1.0f, -1.0f, 0.1f,
5507 -1.0f, 0.0f, 0.1f,
5508 0.0f, -1.0f, 0.1f,
5509 0.0f, 0.0f, 0.1f,
5511 static const float quad2[] =
5513 0.0f, -1.0f, 0.1f,
5514 0.0f, 0.0f, 0.1f,
5515 1.0f, -1.0f, 0.1f,
5516 1.0f, 0.0f, 0.1f,
5518 static const float quad3[] =
5520 0.0f, 0.0f, 0.1f,
5521 0.0f, 1.0f, 0.1f,
5522 1.0f, 0.0f, 0.1f,
5523 1.0f, 1.0f, 0.1f,
5525 static const float quad4[] =
5527 -1.0f, 0.0f, 0.1f,
5528 -1.0f, 1.0f, 0.1f,
5529 0.0f, 0.0f, 0.1f,
5530 0.0f, 1.0f, 0.1f,
5532 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5533 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5535 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5536 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5537 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5538 ok(!!d3d, "Failed to create a D3D object.\n");
5539 if (!(device = create_device(d3d, window, window, TRUE)))
5541 skip("Failed to create a D3D device, skipping tests.\n");
5542 goto done;
5545 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5546 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5547 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
5549 skip("No vs_1_1 support, skipping tests.\n");
5550 IDirect3DDevice9_Release(device);
5551 goto done;
5554 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5557 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5558 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5559 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5560 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5561 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5562 if(FAILED(hr)) shader_20 = NULL;
5563 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5564 if(FAILED(hr)) shader_20_2 = NULL;
5565 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5568 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5569 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5570 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5571 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5572 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5573 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5575 hr = IDirect3DDevice9_BeginScene(device);
5576 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5577 if(SUCCEEDED(hr))
5579 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5580 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5582 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5584 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5585 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5587 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5589 if(shader_20) {
5590 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5591 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5593 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5596 if(shader_20_2) {
5597 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
5598 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5599 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5600 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5603 hr = IDirect3DDevice9_EndScene(device);
5604 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5607 color = getPixelColor(device, 160, 360);
5608 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5609 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
5610 color = getPixelColor(device, 480, 360);
5611 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5612 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
5613 if(shader_20) {
5614 color = getPixelColor(device, 480, 120);
5615 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5616 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
5618 if(shader_20_2) {
5619 color = getPixelColor(device, 160, 120);
5620 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5621 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5626 IDirect3DVertexDeclaration9_Release(decl);
5627 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
5628 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
5629 IDirect3DVertexShader9_Release(shader_11_2);
5630 IDirect3DVertexShader9_Release(shader_11);
5631 refcount = IDirect3DDevice9_Release(device);
5632 ok(!refcount, "Device has %u references left.\n", refcount);
5633 done:
5634 IDirect3D9_Release(d3d);
5635 DestroyWindow(window);
5638 static void constant_clamp_ps_test(void)
5640 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
5641 IDirect3DDevice9 *device;
5642 IDirect3D9 *d3d;
5643 ULONG refcount;
5644 D3DCAPS9 caps;
5645 DWORD color;
5646 HWND window;
5647 HRESULT hr;
5649 static const DWORD shader_code_11[] =
5651 0xffff0101, /* ps_1_1 */
5652 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5653 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5654 0x0000ffff /* end */
5656 static const DWORD shader_code_12[] =
5658 0xffff0102, /* ps_1_2 */
5659 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5660 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5661 0x0000ffff /* end */
5663 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
5664 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
5665 * unlikely that 1.3 shaders are different. During development of this
5666 * test, 1.3 shaders were verified too. */
5667 static const DWORD shader_code_14[] =
5669 0xffff0104, /* ps_1_4 */
5670 /* Try to make one constant local. It gets clamped too, although the
5671 * binary contains the bigger numbers. */
5672 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
5673 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5674 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5675 0x0000ffff /* end */
5677 static const DWORD shader_code_20[] =
5679 0xffff0200, /* ps_2_0 */
5680 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5681 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5682 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5683 0x0000ffff /* end */
5685 static const float quad1[] =
5687 -1.0f, -1.0f, 0.1f,
5688 -1.0f, 0.0f, 0.1f,
5689 0.0f, -1.0f, 0.1f,
5690 0.0f, 0.0f, 0.1f,
5692 static const float quad2[] =
5694 0.0f, -1.0f, 0.1f,
5695 0.0f, 0.0f, 0.1f,
5696 1.0f, -1.0f, 0.1f,
5697 1.0f, 0.0f, 0.1f,
5699 static const float quad3[] =
5701 0.0f, 0.0f, 0.1f,
5702 0.0f, 1.0f, 0.1f,
5703 1.0f, 0.0f, 0.1f,
5704 1.0f, 1.0f, 0.1f,
5706 static const float quad4[] =
5708 -1.0f, 0.0f, 0.1f,
5709 -1.0f, 1.0f, 0.1f,
5710 0.0f, 0.0f, 0.1f,
5711 0.0f, 1.0f, 0.1f,
5713 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5714 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5716 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5717 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5718 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5719 ok(!!d3d, "Failed to create a D3D object.\n");
5720 if (!(device = create_device(d3d, window, window, TRUE)))
5722 skip("Failed to create a D3D device, skipping tests.\n");
5723 goto done;
5726 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5727 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5728 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5730 skip("No ps_1_4 support, skipping tests.\n");
5731 IDirect3DDevice9_Release(device);
5732 goto done;
5735 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5736 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5738 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5739 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5740 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5741 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5742 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5743 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5744 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
5745 if(FAILED(hr)) shader_20 = NULL;
5747 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5748 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5749 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5750 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5751 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5752 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5754 hr = IDirect3DDevice9_BeginScene(device);
5755 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5756 if(SUCCEEDED(hr))
5758 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5759 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5761 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5763 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5764 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5766 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5768 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5771 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5773 if(shader_20) {
5774 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
5777 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780 hr = IDirect3DDevice9_EndScene(device);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5784 color = getPixelColor(device, 160, 360);
5785 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5786 "quad 1 has color %08x, expected 0x00808000\n", color);
5787 color = getPixelColor(device, 480, 360);
5788 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5789 "quad 2 has color %08x, expected 0x00808000\n", color);
5790 color = getPixelColor(device, 480, 120);
5791 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5792 "quad 3 has color %08x, expected 0x00808000\n", color);
5793 if(shader_20) {
5794 color = getPixelColor(device, 160, 120);
5795 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5796 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5798 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5801 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5802 IDirect3DPixelShader9_Release(shader_14);
5803 IDirect3DPixelShader9_Release(shader_12);
5804 IDirect3DPixelShader9_Release(shader_11);
5805 refcount = IDirect3DDevice9_Release(device);
5806 ok(!refcount, "Device has %u references left.\n", refcount);
5807 done:
5808 IDirect3D9_Release(d3d);
5809 DestroyWindow(window);
5812 static void dp2add_ps_test(void)
5814 IDirect3DPixelShader9 *shader_dp2add_sat;
5815 IDirect3DPixelShader9 *shader_dp2add;
5816 IDirect3DDevice9 *device;
5817 IDirect3D9 *d3d;
5818 ULONG refcount;
5819 D3DCAPS9 caps;
5820 DWORD color;
5821 HWND window;
5822 HRESULT hr;
5824 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5825 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5826 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5827 * r0 first.
5828 * The result here for the r,g,b components should be roughly 0.5:
5829 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5830 static const DWORD shader_code_dp2add[] = {
5831 0xffff0200, /* ps_2_0 */
5832 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5834 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5835 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5837 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5838 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5839 0x0000ffff /* end */
5842 /* Test the _sat modifier, too. Result here should be:
5843 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5844 * _SAT: ==> 1.0
5845 * ADD: (1.0 + -0.5) = 0.5
5847 static const DWORD shader_code_dp2add_sat[] = {
5848 0xffff0200, /* ps_2_0 */
5849 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5851 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5852 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5853 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5855 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5856 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5857 0x0000ffff /* end */
5859 static const float quad[] =
5861 -1.0f, -1.0f, 0.1f,
5862 -1.0f, 1.0f, 0.1f,
5863 1.0f, -1.0f, 0.1f,
5864 1.0f, 1.0f, 0.1f,
5867 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5868 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5869 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5870 ok(!!d3d, "Failed to create a D3D object.\n");
5871 if (!(device = create_device(d3d, window, window, TRUE)))
5873 skip("Failed to create a D3D device, skipping tests.\n");
5874 goto done;
5877 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5878 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5879 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
5881 skip("No ps_2_0 support, skipping tests.\n");
5882 IDirect3DDevice9_Release(device);
5883 goto done;
5886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
5887 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5889 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5890 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5892 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5893 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5895 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5896 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5898 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5899 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5900 hr = IDirect3DDevice9_BeginScene(device);
5901 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5903 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
5904 hr = IDirect3DDevice9_EndScene(device);
5905 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5907 color = getPixelColor(device, 360, 240);
5908 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
5910 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5911 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
5912 IDirect3DPixelShader9_Release(shader_dp2add);
5914 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5915 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5916 hr = IDirect3DDevice9_BeginScene(device);
5917 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5919 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
5920 hr = IDirect3DDevice9_EndScene(device);
5921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5923 color = getPixelColor(device, 360, 240);
5924 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
5926 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5927 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
5928 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5930 refcount = IDirect3DDevice9_Release(device);
5931 ok(!refcount, "Device has %u references left.\n", refcount);
5932 done:
5933 IDirect3D9_Release(d3d);
5934 DestroyWindow(window);
5937 static void cnd_test(void)
5939 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
5940 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5941 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5942 IDirect3DDevice9 *device;
5943 IDirect3D9 *d3d;
5944 ULONG refcount;
5945 D3DCAPS9 caps;
5946 HWND window;
5947 DWORD color;
5948 HRESULT hr;
5950 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
5951 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
5952 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
5953 * in 1.x pixel shaders. */
5954 static const DWORD shader_code_11[] =
5956 0xffff0101, /* ps_1_1 */
5957 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5958 0x00000040, 0xb00f0000, /* texcoord t0 */
5959 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5960 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5961 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5962 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5963 0x0000ffff /* end */
5965 static const DWORD shader_code_12[] =
5967 0xffff0102, /* ps_1_2 */
5968 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5969 0x00000040, 0xb00f0000, /* texcoord t0 */
5970 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5971 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5972 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5973 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5974 0x0000ffff /* end */
5976 static const DWORD shader_code_13[] =
5978 0xffff0103, /* ps_1_3 */
5979 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5980 0x00000040, 0xb00f0000, /* texcoord t0 */
5981 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5982 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5983 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5984 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5985 0x0000ffff /* end */
5987 static const DWORD shader_code_14[] =
5989 0xffff0104, /* ps_1_3 */
5990 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5991 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5992 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5993 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5994 0x0000ffff /* end */
5997 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5998 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5999 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6000 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6001 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6002 * well enough.
6004 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6005 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6006 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6007 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6009 static const DWORD shader_code_11_coissue[] =
6011 0xffff0101, /* ps_1_1 */
6012 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6013 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6014 0x00000040, 0xb00f0000, /* texcoord t0 */
6015 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6016 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6017 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6018 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6019 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6020 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6021 0x0000ffff /* end */
6023 static const DWORD shader_code_11_coissue_2[] =
6025 0xffff0101, /* ps_1_1 */
6026 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6027 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6028 0x00000040, 0xb00f0000, /* texcoord t0 */
6029 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6030 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6031 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6032 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6033 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6034 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6035 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6036 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6037 0x0000ffff /* end */
6039 static const DWORD shader_code_12_coissue[] =
6041 0xffff0102, /* ps_1_2 */
6042 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6043 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6044 0x00000040, 0xb00f0000, /* texcoord t0 */
6045 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6046 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6047 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6048 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6049 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6050 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6051 0x0000ffff /* end */
6053 static const DWORD shader_code_12_coissue_2[] =
6055 0xffff0102, /* ps_1_2 */
6056 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6057 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6058 0x00000040, 0xb00f0000, /* texcoord t0 */
6059 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6060 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6061 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6062 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6063 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6064 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6065 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6066 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6067 0x0000ffff /* end */
6069 static const DWORD shader_code_13_coissue[] =
6071 0xffff0103, /* ps_1_3 */
6072 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6073 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6074 0x00000040, 0xb00f0000, /* texcoord t0 */
6075 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6076 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6077 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6078 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6079 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6080 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6081 0x0000ffff /* end */
6083 static const DWORD shader_code_13_coissue_2[] =
6085 0xffff0103, /* ps_1_3 */
6086 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6087 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6088 0x00000040, 0xb00f0000, /* texcoord t0 */
6089 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6090 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6091 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6092 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6093 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6094 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6095 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6096 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6097 0x0000ffff /* end */
6099 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6100 * texcrd result to cnd, it will compare against 0.5. */
6101 static const DWORD shader_code_14_coissue[] =
6103 0xffff0104, /* ps_1_4 */
6104 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6105 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6106 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6107 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6108 0x0000ffff /* end */
6110 static const DWORD shader_code_14_coissue_2[] =
6112 0xffff0104, /* ps_1_4 */
6113 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6114 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6115 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6116 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6117 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6118 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6119 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6120 0x0000ffff /* end */
6122 static const float quad1[] =
6124 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6125 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6126 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6127 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6129 static const float quad2[] =
6131 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6132 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6133 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6134 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6136 static const float quad3[] =
6138 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6139 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6140 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6141 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6143 static const float quad4[] =
6145 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6146 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6147 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6148 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6150 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6151 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6152 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6153 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6155 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6156 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6157 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6158 ok(!!d3d, "Failed to create a D3D object.\n");
6159 if (!(device = create_device(d3d, window, window, TRUE)))
6161 skip("Failed to create a D3D device, skipping tests.\n");
6162 goto done;
6165 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6166 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6167 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6169 skip("No ps_1_4 support, skipping tests.\n");
6170 IDirect3DDevice9_Release(device);
6171 goto done;
6174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6175 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6177 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6178 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6179 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6181 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6182 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6183 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6184 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6185 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6186 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6187 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6188 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6189 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6190 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6191 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6192 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6193 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6194 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6195 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6196 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6197 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6198 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6199 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6200 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6202 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6203 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6204 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6205 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6207 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6209 hr = IDirect3DDevice9_BeginScene(device);
6210 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6211 if(SUCCEEDED(hr))
6213 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6214 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6216 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6218 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6219 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6221 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6223 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6224 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6226 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6228 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6229 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6231 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6233 hr = IDirect3DDevice9_EndScene(device);
6234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6237 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6238 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6240 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6241 color = getPixelColor(device, 158, 118);
6242 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6243 color = getPixelColor(device, 162, 118);
6244 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6245 color = getPixelColor(device, 158, 122);
6246 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6247 color = getPixelColor(device, 162, 122);
6248 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6250 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6251 color = getPixelColor(device, 158, 358);
6252 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6253 color = getPixelColor(device, 162, 358);
6254 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6255 color = getPixelColor(device, 158, 362);
6256 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6257 color = getPixelColor(device, 162, 362);
6258 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6260 /* 1.2 shader */
6261 color = getPixelColor(device, 478, 358);
6262 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6263 color = getPixelColor(device, 482, 358);
6264 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6265 color = getPixelColor(device, 478, 362);
6266 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6267 color = getPixelColor(device, 482, 362);
6268 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6270 /* 1.3 shader */
6271 color = getPixelColor(device, 478, 118);
6272 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6273 color = getPixelColor(device, 482, 118);
6274 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6275 color = getPixelColor(device, 478, 122);
6276 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6277 color = getPixelColor(device, 482, 122);
6278 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6280 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6281 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6283 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6284 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6285 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6286 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6287 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6288 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6290 hr = IDirect3DDevice9_BeginScene(device);
6291 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6292 if(SUCCEEDED(hr))
6294 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6295 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6297 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6299 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6301 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6302 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6304 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6305 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6307 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6309 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6310 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6312 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6314 hr = IDirect3DDevice9_EndScene(device);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6318 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6319 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6321 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6322 * that we swapped the values in c1 and c2 to make the other tests return some color
6324 color = getPixelColor(device, 158, 118);
6325 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6326 color = getPixelColor(device, 162, 118);
6327 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6328 color = getPixelColor(device, 158, 122);
6329 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6330 color = getPixelColor(device, 162, 122);
6331 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6333 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6334 * (The Win7 nvidia driver always selects c2)
6336 color = getPixelColor(device, 158, 358);
6337 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6338 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6339 color = getPixelColor(device, 162, 358);
6340 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6341 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6342 color = getPixelColor(device, 158, 362);
6343 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6344 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6345 color = getPixelColor(device, 162, 362);
6346 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6347 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6349 /* 1.2 shader */
6350 color = getPixelColor(device, 478, 358);
6351 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6352 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6353 color = getPixelColor(device, 482, 358);
6354 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6355 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6356 color = getPixelColor(device, 478, 362);
6357 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6358 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6359 color = getPixelColor(device, 482, 362);
6360 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6361 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6363 /* 1.3 shader */
6364 color = getPixelColor(device, 478, 118);
6365 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6366 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6367 color = getPixelColor(device, 482, 118);
6368 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6369 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6370 color = getPixelColor(device, 478, 122);
6371 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6372 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6373 color = getPixelColor(device, 482, 122);
6374 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6375 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6377 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6378 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6380 /* Retest with the coissue flag on the alpha instruction instead. This
6381 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6382 * the same as coissue on .rgb. */
6383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6384 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6386 hr = IDirect3DDevice9_BeginScene(device);
6387 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6388 if(SUCCEEDED(hr))
6390 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6393 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6395 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6396 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6398 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6400 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6401 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6403 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6405 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6408 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6410 hr = IDirect3DDevice9_EndScene(device);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6414 /* 1.4 shader */
6415 color = getPixelColor(device, 158, 118);
6416 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6417 color = getPixelColor(device, 162, 118);
6418 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6419 color = getPixelColor(device, 158, 122);
6420 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6421 color = getPixelColor(device, 162, 122);
6422 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6424 /* 1.1 shader */
6425 color = getPixelColor(device, 238, 358);
6426 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6427 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6428 color = getPixelColor(device, 242, 358);
6429 ok(color_match(color, 0x00000000, 1),
6430 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6431 color = getPixelColor(device, 238, 362);
6432 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6433 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6434 color = getPixelColor(device, 242, 362);
6435 ok(color_match(color, 0x00000000, 1),
6436 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6438 /* 1.2 shader */
6439 color = getPixelColor(device, 558, 358);
6440 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6441 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6442 color = getPixelColor(device, 562, 358);
6443 ok(color_match(color, 0x00000000, 1),
6444 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6445 color = getPixelColor(device, 558, 362);
6446 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6447 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6448 color = getPixelColor(device, 562, 362);
6449 ok(color_match(color, 0x00000000, 1),
6450 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6452 /* 1.3 shader */
6453 color = getPixelColor(device, 558, 118);
6454 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6455 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6456 color = getPixelColor(device, 562, 118);
6457 ok(color_match(color, 0x00000000, 1),
6458 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6459 color = getPixelColor(device, 558, 122);
6460 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6461 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6462 color = getPixelColor(device, 562, 122);
6463 ok(color_match(color, 0x00000000, 1),
6464 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6466 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6467 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6469 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6470 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6471 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6472 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6473 IDirect3DPixelShader9_Release(shader_14_coissue);
6474 IDirect3DPixelShader9_Release(shader_13_coissue);
6475 IDirect3DPixelShader9_Release(shader_12_coissue);
6476 IDirect3DPixelShader9_Release(shader_11_coissue);
6477 IDirect3DPixelShader9_Release(shader_14);
6478 IDirect3DPixelShader9_Release(shader_13);
6479 IDirect3DPixelShader9_Release(shader_12);
6480 IDirect3DPixelShader9_Release(shader_11);
6481 refcount = IDirect3DDevice9_Release(device);
6482 ok(!refcount, "Device has %u references left.\n", refcount);
6483 done:
6484 IDirect3D9_Release(d3d);
6485 DestroyWindow(window);
6488 static void nested_loop_test(void)
6490 IDirect3DVertexShader9 *vshader;
6491 IDirect3DPixelShader9 *shader;
6492 IDirect3DDevice9 *device;
6493 IDirect3D9 *d3d;
6494 ULONG refcount;
6495 D3DCAPS9 caps;
6496 DWORD color;
6497 HWND window;
6498 HRESULT hr;
6500 static const DWORD shader_code[] =
6502 0xffff0300, /* ps_3_0 */
6503 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6504 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6505 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
6506 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6507 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6508 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6509 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6510 0x0000001d, /* endloop */
6511 0x0000001d, /* endloop */
6512 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6513 0x0000ffff /* end */
6515 static const DWORD vshader_code[] =
6517 0xfffe0300, /* vs_3_0 */
6518 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6519 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6520 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6521 0x0000ffff /* end */
6523 static const float quad[] =
6525 -1.0f, -1.0f, 0.1f,
6526 -1.0f, 1.0f, 0.1f,
6527 1.0f, -1.0f, 0.1f,
6528 1.0f, 1.0f, 0.1f,
6531 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6532 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6533 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6534 ok(!!d3d, "Failed to create a D3D object.\n");
6535 if (!(device = create_device(d3d, window, window, TRUE)))
6537 skip("Failed to create a D3D device, skipping tests.\n");
6538 goto done;
6541 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6542 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6543 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6545 skip("No shader model 3 support, skipping tests.\n");
6546 IDirect3DDevice9_Release(device);
6547 goto done;
6550 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6551 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6552 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6553 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6554 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6555 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6556 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6557 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6558 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6559 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6560 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
6561 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6563 hr = IDirect3DDevice9_BeginScene(device);
6564 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6565 if(SUCCEEDED(hr))
6567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6568 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6569 hr = IDirect3DDevice9_EndScene(device);
6570 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6573 color = getPixelColor(device, 360, 240);
6574 ok(color_match(color, 0x00800000, 1),
6575 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
6577 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6578 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6580 IDirect3DPixelShader9_Release(shader);
6581 IDirect3DVertexShader9_Release(vshader);
6582 refcount = IDirect3DDevice9_Release(device);
6583 ok(!refcount, "Device has %u references left.\n", refcount);
6584 done:
6585 IDirect3D9_Release(d3d);
6586 DestroyWindow(window);
6589 static void pretransformed_varying_test(void)
6591 /* dcl_position: fails to compile */
6592 static const DWORD blendweight_code[] =
6594 0xffff0300, /* ps_3_0 */
6595 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6596 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6597 0x0000ffff /* end */
6599 static const DWORD blendindices_code[] =
6601 0xffff0300, /* ps_3_0 */
6602 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6603 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6604 0x0000ffff /* end */
6606 static const DWORD normal_code[] =
6608 0xffff0300, /* ps_3_0 */
6609 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
6610 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6611 0x0000ffff /* end */
6613 /* psize: fails? */
6614 static const DWORD texcoord0_code[] =
6616 0xffff0300, /* ps_3_0 */
6617 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
6618 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6619 0x0000ffff /* end */
6621 static const DWORD tangent_code[] =
6623 0xffff0300, /* ps_3_0 */
6624 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
6625 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6626 0x0000ffff /* end */
6628 static const DWORD binormal_code[] =
6630 0xffff0300, /* ps_3_0 */
6631 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
6632 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6633 0x0000ffff /* end */
6635 /* tessfactor: fails */
6636 /* positiont: fails */
6637 static const DWORD color_code[] =
6639 0xffff0300, /* ps_3_0 */
6640 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
6641 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6642 0x0000ffff /* end */
6644 static const DWORD fog_code[] =
6646 0xffff0300, /* ps_3_0 */
6647 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
6648 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6649 0x0000ffff /* end */
6651 static const DWORD depth_code[] =
6653 0xffff0300, /* ps_3_0 */
6654 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
6655 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6656 0x0000ffff /* end */
6658 static const DWORD specular_code[] =
6660 0xffff0300, /* ps_3_0 */
6661 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
6662 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6663 0x0000ffff /* end */
6665 /* sample: fails */
6667 static const struct
6669 const char *name;
6670 const DWORD *shader_code;
6671 DWORD color;
6672 BOOL todo;
6674 tests[] =
6676 {"blendweight", blendweight_code, 0x00191919, TRUE },
6677 {"blendindices", blendindices_code, 0x00333333, TRUE },
6678 {"normal", normal_code, 0x004c4c4c, TRUE },
6679 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
6680 {"tangent", tangent_code, 0x00999999, TRUE },
6681 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
6682 {"color", color_code, 0x00e6e6e6, FALSE},
6683 {"fog", fog_code, 0x00666666, TRUE },
6684 {"depth", depth_code, 0x00cccccc, TRUE },
6685 {"specular", specular_code, 0x004488ff, FALSE},
6687 /* Declare a monster vertex type :-) */
6688 static const D3DVERTEXELEMENT9 decl_elements[] = {
6689 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6690 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
6691 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
6692 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
6693 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
6694 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6695 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
6696 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
6697 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
6698 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6699 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
6700 D3DDECL_END()
6703 static const struct
6705 float pos_x, pos_y, pos_z, rhw;
6706 float weight_1, weight_2, weight_3, weight_4;
6707 float index_1, index_2, index_3, index_4;
6708 float normal_1, normal_2, normal_3, normal_4;
6709 float fog_1, fog_2, fog_3, fog_4;
6710 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
6711 float tangent_1, tangent_2, tangent_3, tangent_4;
6712 float binormal_1, binormal_2, binormal_3, binormal_4;
6713 float depth_1, depth_2, depth_3, depth_4;
6714 D3DCOLOR diffuse;
6715 D3DCOLOR specular;
6717 data[] =
6720 0.0f, 0.0f, 0.1f, 1.0f,
6721 0.1f, 0.1f, 0.1f, 0.1f,
6722 0.2f, 0.2f, 0.2f, 0.2f,
6723 0.3f, 0.3f, 0.3f, 0.3f,
6724 0.4f, 0.4f, 0.4f, 0.4f,
6725 0.5f, 0.55f, 0.55f, 0.55f,
6726 0.6f, 0.6f, 0.6f, 0.7f,
6727 0.7f, 0.7f, 0.7f, 0.6f,
6728 0.8f, 0.8f, 0.8f, 0.8f,
6729 0xe6e6e6e6, /* 0.9 * 256 */
6730 0x224488ff, /* Nothing special */
6733 640.0f, 0.0f, 0.1f, 1.0f,
6734 0.1f, 0.1f, 0.1f, 0.1f,
6735 0.2f, 0.2f, 0.2f, 0.2f,
6736 0.3f, 0.3f, 0.3f, 0.3f,
6737 0.4f, 0.4f, 0.4f, 0.4f,
6738 0.5f, 0.55f, 0.55f, 0.55f,
6739 0.6f, 0.6f, 0.6f, 0.7f,
6740 0.7f, 0.7f, 0.7f, 0.6f,
6741 0.8f, 0.8f, 0.8f, 0.8f,
6742 0xe6e6e6e6, /* 0.9 * 256 */
6743 0x224488ff, /* Nothing special */
6746 0.0f, 480.0f, 0.1f, 1.0f,
6747 0.1f, 0.1f, 0.1f, 0.1f,
6748 0.2f, 0.2f, 0.2f, 0.2f,
6749 0.3f, 0.3f, 0.3f, 0.3f,
6750 0.4f, 0.4f, 0.4f, 0.4f,
6751 0.5f, 0.55f, 0.55f, 0.55f,
6752 0.6f, 0.6f, 0.6f, 0.7f,
6753 0.7f, 0.7f, 0.7f, 0.6f,
6754 0.8f, 0.8f, 0.8f, 0.8f,
6755 0xe6e6e6e6, /* 0.9 * 256 */
6756 0x224488ff, /* Nothing special */
6759 640.0f, 480.0f, 0.1f, 1.0f,
6760 0.1f, 0.1f, 0.1f, 0.1f,
6761 0.2f, 0.2f, 0.2f, 0.2f,
6762 0.3f, 0.3f, 0.3f, 0.3f,
6763 0.4f, 0.4f, 0.4f, 0.4f,
6764 0.5f, 0.55f, 0.55f, 0.55f,
6765 0.6f, 0.6f, 0.6f, 0.7f,
6766 0.7f, 0.7f, 0.7f, 0.6f,
6767 0.8f, 0.8f, 0.8f, 0.8f,
6768 0xe6e6e6e6, /* 0.9 * 256 */
6769 0x224488ff, /* Nothing special */
6772 IDirect3DVertexDeclaration9 *decl;
6773 IDirect3DDevice9 *device;
6774 IDirect3D9 *d3d;
6775 unsigned int i;
6776 ULONG refcount;
6777 D3DCAPS9 caps;
6778 DWORD color;
6779 HWND window;
6780 HRESULT hr;
6782 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6783 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6784 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6785 ok(!!d3d, "Failed to create a D3D object.\n");
6786 if (!(device = create_device(d3d, window, window, TRUE)))
6788 skip("Failed to create a D3D device, skipping tests.\n");
6789 goto done;
6792 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6793 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6794 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6796 skip("No shader model 3 support, skipping tests.\n");
6797 IDirect3DDevice9_Release(device);
6798 goto done;
6801 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6802 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6803 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6804 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6806 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6807 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6808 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6810 IDirect3DPixelShader9 *shader;
6812 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
6813 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6815 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
6816 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
6818 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6819 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6821 hr = IDirect3DDevice9_BeginScene(device);
6822 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6823 if(SUCCEEDED(hr))
6825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
6826 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6827 hr = IDirect3DDevice9_EndScene(device);
6828 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6831 /* This isn't a weekend's job to fix, ignore the problem for now.
6832 * Needs a replacement pipeline. */
6833 color = getPixelColor(device, 360, 240);
6834 if (tests[i].todo)
6835 todo_wine ok(color_match(color, tests[i].color, 1)
6836 || broken(color_match(color, 0x00000000, 1)
6837 && tests[i].shader_code == blendindices_code),
6838 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
6839 tests[i].name, color, tests[i].color);
6840 else
6841 ok(color_match(color, tests[i].color, 1),
6842 "Test %s returned color 0x%08x, expected 0x%08x.\n",
6843 tests[i].name, color, tests[i].color);
6845 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6846 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6848 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6849 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
6850 IDirect3DPixelShader9_Release(shader);
6853 IDirect3DVertexDeclaration9_Release(decl);
6854 refcount = IDirect3DDevice9_Release(device);
6855 ok(!refcount, "Device has %u references left.\n", refcount);
6856 done:
6857 IDirect3D9_Release(d3d);
6858 DestroyWindow(window);
6861 static void test_compare_instructions(void)
6863 IDirect3DVertexShader9 *shader_slt_scalar;
6864 IDirect3DVertexShader9 *shader_sge_scalar;
6865 IDirect3DVertexShader9 *shader_slt_vec;
6866 IDirect3DVertexShader9 *shader_sge_vec;
6867 IDirect3DDevice9 *device;
6868 IDirect3D9 *d3d;
6869 D3DCOLOR color;
6870 ULONG refcount;
6871 D3DCAPS9 caps;
6872 HWND window;
6873 HRESULT hr;
6875 static const DWORD shader_sge_vec_code[] =
6877 0xfffe0101, /* vs_1_1 */
6878 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6879 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6880 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6881 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
6882 0x0000ffff /* end */
6884 static const DWORD shader_slt_vec_code[] =
6886 0xfffe0101, /* vs_1_1 */
6887 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6888 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6889 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6890 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
6891 0x0000ffff /* end */
6893 static const DWORD shader_sge_scalar_code[] =
6895 0xfffe0101, /* vs_1_1 */
6896 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6897 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6898 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6899 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
6900 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
6901 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
6902 0x0000ffff /* end */
6904 static const DWORD shader_slt_scalar_code[] =
6906 0xfffe0101, /* vs_1_1 */
6907 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6908 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6909 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6910 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
6911 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
6912 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
6913 0x0000ffff /* end */
6915 static const float quad1[] =
6917 -1.0f, -1.0f, 0.1f,
6918 -1.0f, 0.0f, 0.1f,
6919 0.0f, -1.0f, 0.1f,
6920 0.0f, 0.0f, 0.1f,
6922 static const float quad2[] =
6924 0.0f, -1.0f, 0.1f,
6925 0.0f, 0.0f, 0.1f,
6926 1.0f, -1.0f, 0.1f,
6927 1.0f, 0.0f, 0.1f,
6929 static const float quad3[] =
6931 -1.0f, 0.0f, 0.1f,
6932 -1.0f, 1.0f, 0.1f,
6933 0.0f, 0.0f, 0.1f,
6934 0.0f, 1.0f, 0.1f,
6936 static const float quad4[] =
6938 0.0f, 0.0f, 0.1f,
6939 0.0f, 1.0f, 0.1f,
6940 1.0f, 0.0f, 0.1f,
6941 1.0f, 1.0f, 0.1f,
6943 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
6944 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
6946 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6947 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6948 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6949 ok(!!d3d, "Failed to create a D3D object.\n");
6950 if (!(device = create_device(d3d, window, window, TRUE)))
6952 skip("Failed to create a D3D device, skipping tests.\n");
6953 goto done;
6956 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6957 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6958 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6960 skip("No vs_1_1 support, skipping tests.\n");
6961 IDirect3DDevice9_Release(device);
6962 goto done;
6965 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
6966 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6968 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6969 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6970 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6971 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6972 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6973 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6974 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6975 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6976 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6977 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6978 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6979 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6980 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6981 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6983 hr = IDirect3DDevice9_BeginScene(device);
6984 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6985 if(SUCCEEDED(hr))
6987 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6990 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6992 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6993 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6994 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
6995 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6997 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6999 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7000 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7002 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7003 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7005 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7006 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7007 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7008 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7010 hr = IDirect3DDevice9_EndScene(device);
7011 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7014 color = getPixelColor(device, 160, 360);
7015 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7016 color = getPixelColor(device, 480, 360);
7017 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7018 color = getPixelColor(device, 160, 120);
7019 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7020 color = getPixelColor(device, 480, 160);
7021 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7023 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7024 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7026 IDirect3DVertexShader9_Release(shader_sge_vec);
7027 IDirect3DVertexShader9_Release(shader_slt_vec);
7028 IDirect3DVertexShader9_Release(shader_sge_scalar);
7029 IDirect3DVertexShader9_Release(shader_slt_scalar);
7030 refcount = IDirect3DDevice9_Release(device);
7031 ok(!refcount, "Device has %u references left.\n", refcount);
7032 done:
7033 IDirect3D9_Release(d3d);
7034 DestroyWindow(window);
7037 static void test_vshader_input(void)
7039 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7040 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7041 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7042 D3DADAPTER_IDENTIFIER9 identifier;
7043 IDirect3DPixelShader9 *ps;
7044 IDirect3DDevice9 *device;
7045 IDirect3D9 *d3d;
7046 ULONG refcount;
7047 unsigned int i;
7048 D3DCAPS9 caps;
7049 DWORD color;
7050 HWND window;
7051 HRESULT hr;
7052 BOOL warp;
7054 static const DWORD swapped_shader_code_3[] =
7056 0xfffe0300, /* vs_3_0 */
7057 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7058 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7059 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7060 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7061 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7062 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7063 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7064 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7065 0x0000ffff /* end */
7067 static const DWORD swapped_shader_code_1[] =
7069 0xfffe0101, /* vs_1_1 */
7070 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7071 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7072 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7073 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7074 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7075 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7076 0x0000ffff /* end */
7078 static const DWORD swapped_shader_code_2[] =
7080 0xfffe0200, /* vs_2_0 */
7081 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7082 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7083 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7084 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7085 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7086 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7087 0x0000ffff /* end */
7089 static const DWORD texcoord_color_shader_code_3[] =
7091 0xfffe0300, /* vs_3_0 */
7092 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7093 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7094 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7095 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7096 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7097 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7098 0x0000ffff /* end */
7100 static const DWORD texcoord_color_shader_code_2[] =
7102 0xfffe0200, /* vs_2_0 */
7103 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7104 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7105 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7106 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7107 0x0000ffff /* end */
7109 static const DWORD texcoord_color_shader_code_1[] =
7111 0xfffe0101, /* vs_1_1 */
7112 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7113 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7114 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7115 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7116 0x0000ffff /* end */
7118 static const DWORD color_color_shader_code_3[] =
7120 0xfffe0300, /* vs_3_0 */
7121 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7122 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7123 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7124 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7125 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7126 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7127 0x0000ffff /* end */
7129 static const DWORD color_color_shader_code_2[] =
7131 0xfffe0200, /* vs_2_0 */
7132 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7133 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7134 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7135 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7136 0x0000ffff /* end */
7138 static const DWORD color_color_shader_code_1[] =
7140 0xfffe0101, /* vs_1_1 */
7141 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7142 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7143 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7144 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7145 0x0000ffff /* end */
7147 static const DWORD ps3_code[] =
7149 0xffff0300, /* ps_3_0 */
7150 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7151 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7152 0x0000ffff /* end */
7154 static const float quad1[] =
7156 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7157 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7158 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7159 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7161 static const float quad2[] =
7163 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7164 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7165 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7166 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7168 static const float quad3[] =
7170 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7171 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7172 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7173 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7175 static const float quad4[] =
7177 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7178 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7179 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7180 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7182 static const float quad1_modified[] =
7184 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7185 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7186 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7187 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7189 static const float quad2_modified[] =
7191 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7192 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7193 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7194 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7196 static const struct vertex quad1_color[] =
7198 {-1.0f, -1.0f, 0.1f, 0x00ff8040},
7199 {-1.0f, 0.0f, 0.1f, 0x00ff8040},
7200 { 0.0f, -1.0f, 0.1f, 0x00ff8040},
7201 { 0.0f, 0.0f, 0.1f, 0x00ff8040},
7203 static const struct vertex quad2_color[] =
7205 { 0.0f, -1.0f, 0.1f, 0x00ff8040},
7206 { 0.0f, 0.0f, 0.1f, 0x00ff8040},
7207 { 1.0f, -1.0f, 0.1f, 0x00ff8040},
7208 { 1.0f, 0.0f, 0.1f, 0x00ff8040},
7210 static const struct vertex quad3_color[] =
7212 {-1.0f, 0.0f, 0.1f, 0x00ff8040},
7213 {-1.0f, 1.0f, 0.1f, 0x00ff8040},
7214 { 0.0f, 0.0f, 0.1f, 0x00ff8040},
7215 { 0.0f, 1.0f, 0.1f, 0x00ff8040},
7217 static const float quad4_color[] =
7219 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7220 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7221 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7222 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7224 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7226 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7227 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7228 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7229 D3DDECL_END()
7231 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7233 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7234 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7235 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7236 D3DDECL_END()
7238 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7240 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7241 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7242 D3DDECL_END()
7244 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7246 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7247 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7248 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7249 D3DDECL_END()
7251 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7253 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7254 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7255 D3DDECL_END()
7257 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7259 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7260 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7261 D3DDECL_END()
7263 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7265 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7266 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7267 D3DDECL_END()
7269 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7271 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7272 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7273 D3DDECL_END()
7275 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7276 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7278 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7279 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7280 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7281 ok(!!d3d, "Failed to create a D3D object.\n");
7282 if (!(device = create_device(d3d, window, window, TRUE)))
7284 skip("Failed to create a D3D device, skipping tests.\n");
7285 goto done;
7288 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7289 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7290 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7292 skip("No vs_3_0 support, skipping tests.\n");
7293 IDirect3DDevice9_Release(device);
7294 goto done;
7297 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7298 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7299 warp = !strcmp(identifier.Description, "Microsoft Basic Render Driver");
7301 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7302 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7303 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7304 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7305 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7307 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7308 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7310 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7311 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7312 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7313 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7314 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7315 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7316 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7317 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7319 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7320 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7322 for (i = 1; i <= 3; ++i)
7324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7325 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7326 if(i == 3) {
7327 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7328 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7329 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7330 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7331 } else if(i == 2){
7332 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7333 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7334 } else if(i == 1) {
7335 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7336 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7339 hr = IDirect3DDevice9_BeginScene(device);
7340 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7341 if(SUCCEEDED(hr))
7343 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7344 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7346 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7349 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7351 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7354 if(i == 3 || i == 2) {
7355 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7356 } else if(i == 1) {
7357 /* Succeeds or fails, depending on SW or HW vertex processing */
7358 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
7361 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7362 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7363 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7364 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7366 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7367 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7369 if(i == 3 || i == 2) {
7370 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7371 } else if(i == 1) {
7372 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
7375 hr = IDirect3DDevice9_EndScene(device);
7376 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7379 if(i == 3 || i == 2) {
7380 color = getPixelColor(device, 160, 360);
7381 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7382 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7384 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7385 color = getPixelColor(device, 480, 360);
7386 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7387 * mostly random data as input. */
7388 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7389 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7390 color = getPixelColor(device, 160, 120);
7391 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7392 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7393 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7395 color = getPixelColor(device, 480, 160);
7396 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7397 } else if(i == 1) {
7398 color = getPixelColor(device, 160, 360);
7399 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7400 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7401 color = getPixelColor(device, 480, 360);
7402 /* Accept the clear color as well in this case, since SW VP
7403 * returns an error. On the Windows 8 testbot (WARP) the draw
7404 * succeeds, but uses mostly random data as input. */
7405 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7406 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7407 color = getPixelColor(device, 160, 120);
7408 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7409 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7410 color = getPixelColor(device, 480, 160);
7411 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7414 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7415 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7417 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7418 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7420 /* Now find out if the whole streams are re-read, or just the last active value for the
7421 * vertices is used.
7423 hr = IDirect3DDevice9_BeginScene(device);
7424 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7425 if(SUCCEEDED(hr))
7427 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7428 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7430 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7431 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7433 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7435 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7436 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7438 if(i == 3 || i == 2) {
7439 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
7440 } else if(i == 1) {
7441 /* Succeeds or fails, depending on SW or HW vertex processing */
7442 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
7445 hr = IDirect3DDevice9_EndScene(device);
7446 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7449 color = getPixelColor(device, 480, 350);
7450 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7451 * as well.
7453 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7454 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7455 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7456 * refrast's result.
7458 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7460 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7461 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7462 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7465 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7467 IDirect3DDevice9_SetVertexShader(device, NULL);
7468 IDirect3DDevice9_SetPixelShader(device, NULL);
7469 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7471 IDirect3DVertexShader9_Release(swapped_shader);
7474 for (i = 1; i <= 3; ++i)
7476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7477 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7478 if(i == 3) {
7479 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
7480 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7481 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
7482 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7483 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7484 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7485 } else if(i == 2){
7486 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
7487 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7488 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7490 } else if(i == 1) {
7491 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
7492 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7493 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
7494 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7497 hr = IDirect3DDevice9_BeginScene(device);
7498 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7499 if(SUCCEEDED(hr))
7501 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7503 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
7504 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7506 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7508 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
7509 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7511 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
7512 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7513 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
7514 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7516 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7518 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7520 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
7521 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7522 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7523 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7525 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
7526 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7527 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7528 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7530 hr = IDirect3DDevice9_EndScene(device);
7531 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7533 IDirect3DDevice9_SetVertexShader(device, NULL);
7534 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7535 IDirect3DDevice9_SetPixelShader(device, NULL);
7537 color = getPixelColor(device, 160, 360);
7538 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7539 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7540 color = getPixelColor(device, 480, 360);
7541 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7542 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7543 color = getPixelColor(device, 160, 120);
7544 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7545 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7546 color = getPixelColor(device, 480, 160);
7547 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7548 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7550 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7551 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7553 IDirect3DVertexShader9_Release(texcoord_color_shader);
7554 IDirect3DVertexShader9_Release(color_color_shader);
7557 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
7558 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
7559 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
7560 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
7562 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
7563 IDirect3DVertexDeclaration9_Release(decl_color_color);
7564 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
7565 IDirect3DVertexDeclaration9_Release(decl_color_float);
7567 IDirect3DPixelShader9_Release(ps);
7568 refcount = IDirect3DDevice9_Release(device);
7569 ok(!refcount, "Device has %u references left.\n", refcount);
7570 done:
7571 IDirect3D9_Release(d3d);
7572 DestroyWindow(window);
7575 static void srgbtexture_test(IDirect3DDevice9 *device)
7577 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
7578 * texture stage state to render a quad using that texture. The resulting
7579 * color components should be 0x36 (~ 0.21), per this formula:
7580 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
7581 * This is true where srgb_color > 0.04045. */
7582 struct IDirect3DTexture9 *texture = NULL;
7583 struct IDirect3DSurface9 *surface = NULL;
7584 IDirect3D9 *d3d = NULL;
7585 HRESULT hr;
7586 D3DLOCKED_RECT lr;
7587 DWORD color;
7588 float quad[] = {
7589 -1.0, 1.0, 0.0, 0.0, 0.0,
7590 1.0, 1.0, 0.0, 1.0, 0.0,
7591 -1.0, -1.0, 0.0, 0.0, 1.0,
7592 1.0, -1.0, 0.0, 1.0, 1.0,
7596 memset(&lr, 0, sizeof(lr));
7597 IDirect3DDevice9_GetDirect3D(device, &d3d);
7598 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7599 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
7600 D3DFMT_A8R8G8B8) != D3D_OK) {
7601 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
7602 goto out;
7605 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
7606 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
7607 &texture, NULL);
7608 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
7609 if(!texture) {
7610 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
7611 goto out;
7613 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7614 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
7616 fill_surface(surface, 0xff7f7f7f, 0);
7617 IDirect3DSurface9_Release(surface);
7619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7620 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7621 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7622 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7624 hr = IDirect3DDevice9_BeginScene(device);
7625 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7626 if(SUCCEEDED(hr))
7628 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
7629 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7632 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7635 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
7636 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
7638 hr = IDirect3DDevice9_EndScene(device);
7639 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7642 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7643 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
7644 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
7645 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
7647 color = getPixelColor(device, 320, 240);
7648 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
7650 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7653 out:
7654 if(texture) IDirect3DTexture9_Release(texture);
7655 IDirect3D9_Release(d3d);
7658 static void shademode_test(IDirect3DDevice9 *device)
7660 /* Render a quad and try all of the different fixed function shading models. */
7661 struct IDirect3DVertexBuffer9 *vb_strip = NULL;
7662 struct IDirect3DVertexBuffer9 *vb_list = NULL;
7663 HRESULT hr;
7664 DWORD color0, color1;
7665 DWORD color0_gouraud = 0, color1_gouraud = 0;
7666 DWORD shademode = D3DSHADE_FLAT;
7667 DWORD primtype = D3DPT_TRIANGLESTRIP;
7668 void *data = NULL;
7669 UINT i, j;
7670 struct vertex quad_strip[] =
7672 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7673 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7674 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7675 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7677 struct vertex quad_list[] =
7679 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
7680 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7681 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7683 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
7684 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
7685 { 1.0f, 1.0f, 0.0f, 0xffffffff }
7688 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
7689 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
7690 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7691 if (FAILED(hr)) goto bail;
7693 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
7694 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
7695 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7696 if (FAILED(hr)) goto bail;
7698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7702 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7704 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
7705 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7706 memcpy(data, quad_strip, sizeof(quad_strip));
7707 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
7708 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7710 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
7711 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7712 memcpy(data, quad_list, sizeof(quad_list));
7713 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
7714 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
7716 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
7717 * the color fixups we have to do for FLAT shading will be dependent on that. */
7718 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
7719 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7721 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
7722 for (j=0; j<2; j++) {
7724 /* Inner loop just changes the D3DRS_SHADEMODE */
7725 for (i=0; i<3; i++) {
7726 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7727 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
7730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7732 hr = IDirect3DDevice9_BeginScene(device);
7733 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7734 if(SUCCEEDED(hr))
7736 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
7737 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
7739 hr = IDirect3DDevice9_EndScene(device);
7740 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7743 /* Sample two spots from the output */
7744 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
7745 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
7746 switch(shademode) {
7747 case D3DSHADE_FLAT:
7748 /* Should take the color of the first vertex of each triangle */
7749 if (0)
7751 /* This test depends on EXT_provoking_vertex being
7752 * available. This extension is currently (20090810)
7753 * not common enough to let the test fail if it isn't
7754 * present. */
7755 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
7756 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
7758 shademode = D3DSHADE_GOURAUD;
7759 break;
7760 case D3DSHADE_GOURAUD:
7761 /* Should be an interpolated blend */
7763 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7764 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
7765 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7766 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
7768 color0_gouraud = color0;
7769 color1_gouraud = color1;
7771 shademode = D3DSHADE_PHONG;
7772 break;
7773 case D3DSHADE_PHONG:
7774 /* Should be the same as GOURAUD, since no hardware implements this */
7775 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7776 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7777 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7778 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7780 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7781 color0_gouraud, color0);
7782 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7783 color1_gouraud, color1);
7784 break;
7788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7791 /* Now, do it all over again with a TRIANGLELIST */
7792 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7793 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7794 primtype = D3DPT_TRIANGLELIST;
7795 shademode = D3DSHADE_FLAT;
7798 bail:
7799 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7800 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7802 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7804 if (vb_strip)
7805 IDirect3DVertexBuffer9_Release(vb_strip);
7806 if (vb_list)
7807 IDirect3DVertexBuffer9_Release(vb_list);
7810 static void alpha_test(IDirect3DDevice9 *device)
7812 HRESULT hr;
7813 IDirect3DTexture9 *offscreenTexture;
7814 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7815 DWORD color;
7817 struct vertex quad1[] =
7819 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
7820 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
7821 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
7822 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
7824 struct vertex quad2[] =
7826 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
7827 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
7828 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
7829 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
7831 static const float composite_quad[][5] = {
7832 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7833 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
7834 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7835 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
7838 /* Clear the render target with alpha = 0.5 */
7839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7840 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7842 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7843 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7845 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7846 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7847 if(!backbuffer) {
7848 goto out;
7851 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7852 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7853 if(!offscreen) {
7854 goto out;
7857 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7858 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7860 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7861 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7862 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7863 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7864 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7865 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7866 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7867 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7869 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7872 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7873 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7875 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7881 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7886 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7887 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7888 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7890 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7891 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7892 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7893 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7894 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7895 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7896 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7899 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7903 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7906 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7910 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7912 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7913 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7915 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7916 * Disable alpha blending for the final composition
7918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7919 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7921 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7923 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7926 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7927 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7928 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7930 hr = IDirect3DDevice9_EndScene(device);
7931 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7934 color = getPixelColor(device, 160, 360);
7935 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7936 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7938 color = getPixelColor(device, 160, 120);
7939 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7940 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7942 color = getPixelColor(device, 480, 360);
7943 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7944 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7946 color = getPixelColor(device, 480, 120);
7947 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7948 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7950 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7952 out:
7953 /* restore things */
7954 if(backbuffer) {
7955 IDirect3DSurface9_Release(backbuffer);
7957 if(offscreenTexture) {
7958 IDirect3DTexture9_Release(offscreenTexture);
7960 if(offscreen) {
7961 IDirect3DSurface9_Release(offscreen);
7965 struct vertex_shortcolor {
7966 float x, y, z;
7967 unsigned short r, g, b, a;
7969 struct vertex_floatcolor {
7970 float x, y, z;
7971 float r, g, b, a;
7974 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7976 HRESULT hr;
7977 BOOL s_ok, ub_ok, f_ok;
7978 DWORD color, size, i;
7979 void *data;
7980 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7982 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7983 D3DDECL_END()
7985 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7987 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7988 D3DDECL_END()
7990 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7991 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7992 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7993 D3DDECL_END()
7995 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7996 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7997 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7998 D3DDECL_END()
8000 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8001 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8002 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8003 D3DDECL_END()
8005 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8006 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8007 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8008 D3DDECL_END()
8010 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8011 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8012 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8013 D3DDECL_END()
8015 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8016 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
8017 IDirect3DVertexBuffer9 *vb, *vb2;
8018 struct vertex quad1[] = /* D3DCOLOR */
8020 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
8021 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
8022 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
8023 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
8025 struct vertex quad2[] = /* UBYTE4N */
8027 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
8028 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
8029 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
8030 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
8032 struct vertex_shortcolor quad3[] = /* short */
8034 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8035 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8036 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8037 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
8039 struct vertex_floatcolor quad4[] =
8041 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8042 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8043 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8044 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
8046 DWORD colors[] = {
8047 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8048 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8049 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8050 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8051 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8052 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8053 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8054 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8055 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8056 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8057 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8058 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8059 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8060 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8061 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8062 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8064 float quads[] = {
8065 -1.0, -1.0, 0.1,
8066 -1.0, 0.0, 0.1,
8067 0.0, -1.0, 0.1,
8068 0.0, 0.0, 0.1,
8070 0.0, -1.0, 0.1,
8071 0.0, 0.0, 0.1,
8072 1.0, -1.0, 0.1,
8073 1.0, 0.0, 0.1,
8075 0.0, 0.0, 0.1,
8076 0.0, 1.0, 0.1,
8077 1.0, 0.0, 0.1,
8078 1.0, 1.0, 0.1,
8080 -1.0, 0.0, 0.1,
8081 -1.0, 1.0, 0.1,
8082 0.0, 0.0, 0.1,
8083 0.0, 1.0, 0.1
8085 struct tvertex quad_transformed[] = {
8086 { 90, 110, 0.1, 2.0, 0x00ffff00},
8087 { 570, 110, 0.1, 2.0, 0x00ffff00},
8088 { 90, 300, 0.1, 2.0, 0x00ffff00},
8089 { 570, 300, 0.1, 2.0, 0x00ffff00}
8091 D3DCAPS9 caps;
8093 memset(&caps, 0, sizeof(caps));
8094 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8095 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8098 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8100 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8101 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8102 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8103 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8104 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8105 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8106 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8107 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8108 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8109 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8110 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8111 } else {
8112 trace("D3DDTCAPS_UBYTE4N not supported\n");
8113 dcl_ubyte_2 = NULL;
8114 dcl_ubyte = NULL;
8116 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8117 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8118 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8119 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8121 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8122 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8123 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8124 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8126 hr = IDirect3DDevice9_BeginScene(device);
8127 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8128 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8129 if(SUCCEEDED(hr)) {
8130 if(dcl_color) {
8131 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8132 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8134 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8137 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
8138 * accepts them, the nvidia driver accepts them all. All those differences even though we're
8139 * using software vertex processing. Doh!
8141 if(dcl_ubyte) {
8142 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8143 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8145 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8146 ub_ok = SUCCEEDED(hr);
8149 if(dcl_short) {
8150 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8153 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8154 s_ok = SUCCEEDED(hr);
8157 if(dcl_float) {
8158 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8161 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8162 f_ok = SUCCEEDED(hr);
8165 hr = IDirect3DDevice9_EndScene(device);
8166 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
8169 if(dcl_short) {
8170 color = getPixelColor(device, 480, 360);
8171 ok(color == 0x000000ff || !s_ok,
8172 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8174 if(dcl_ubyte) {
8175 color = getPixelColor(device, 160, 120);
8176 ok(color == 0x0000ffff || !ub_ok,
8177 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8179 if(dcl_color) {
8180 color = getPixelColor(device, 160, 360);
8181 ok(color == 0x00ffff00,
8182 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8184 if(dcl_float) {
8185 color = getPixelColor(device, 480, 120);
8186 ok(color == 0x00ff0000 || !f_ok,
8187 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8189 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8191 /* The following test with vertex buffers doesn't serve to find out new information from windows.
8192 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
8193 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
8194 * whether the immediate mode code works
8196 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8197 hr = IDirect3DDevice9_BeginScene(device);
8198 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8199 if(SUCCEEDED(hr)) {
8200 if(dcl_color) {
8201 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8202 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8203 memcpy(data, quad1, sizeof(quad1));
8204 hr = IDirect3DVertexBuffer9_Unlock(vb);
8205 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8206 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8207 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8208 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8209 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8210 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8211 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8214 if(dcl_ubyte) {
8215 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8216 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8217 memcpy(data, quad2, sizeof(quad2));
8218 hr = IDirect3DVertexBuffer9_Unlock(vb);
8219 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8220 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8222 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8223 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8224 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8225 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8226 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8227 ub_ok = SUCCEEDED(hr);
8230 if(dcl_short) {
8231 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8232 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8233 memcpy(data, quad3, sizeof(quad3));
8234 hr = IDirect3DVertexBuffer9_Unlock(vb);
8235 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8236 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8238 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8239 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8240 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8241 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8242 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8243 s_ok = SUCCEEDED(hr);
8246 if(dcl_float) {
8247 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8248 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8249 memcpy(data, quad4, sizeof(quad4));
8250 hr = IDirect3DVertexBuffer9_Unlock(vb);
8251 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8252 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8253 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8254 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8255 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8256 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8257 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8258 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8259 f_ok = SUCCEEDED(hr);
8262 hr = IDirect3DDevice9_EndScene(device);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
8266 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8267 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8268 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8269 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
8271 if(dcl_short) {
8272 color = getPixelColor(device, 480, 360);
8273 ok(color == 0x000000ff || !s_ok,
8274 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8276 if(dcl_ubyte) {
8277 color = getPixelColor(device, 160, 120);
8278 ok(color == 0x0000ffff || !ub_ok,
8279 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8281 if(dcl_color) {
8282 color = getPixelColor(device, 160, 360);
8283 ok(color == 0x00ffff00,
8284 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8286 if(dcl_float) {
8287 color = getPixelColor(device, 480, 120);
8288 ok(color == 0x00ff0000 || !f_ok,
8289 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8291 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8296 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
8297 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8298 memcpy(data, quad_transformed, sizeof(quad_transformed));
8299 hr = IDirect3DVertexBuffer9_Unlock(vb);
8300 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8302 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
8303 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8305 hr = IDirect3DDevice9_BeginScene(device);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8307 if(SUCCEEDED(hr)) {
8308 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
8309 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8310 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8311 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8313 hr = IDirect3DDevice9_EndScene(device);
8314 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8317 color = getPixelColor(device, 88, 108);
8318 ok(color == 0x000000ff,
8319 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8320 color = getPixelColor(device, 92, 108);
8321 ok(color == 0x000000ff,
8322 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8323 color = getPixelColor(device, 88, 112);
8324 ok(color == 0x000000ff,
8325 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8326 color = getPixelColor(device, 92, 112);
8327 ok(color == 0x00ffff00,
8328 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8330 color = getPixelColor(device, 568, 108);
8331 ok(color == 0x000000ff,
8332 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8333 color = getPixelColor(device, 572, 108);
8334 ok(color == 0x000000ff,
8335 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8336 color = getPixelColor(device, 568, 112);
8337 ok(color == 0x00ffff00,
8338 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8339 color = getPixelColor(device, 572, 112);
8340 ok(color == 0x000000ff,
8341 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8343 color = getPixelColor(device, 88, 298);
8344 ok(color == 0x000000ff,
8345 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8346 color = getPixelColor(device, 92, 298);
8347 ok(color == 0x00ffff00,
8348 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8349 color = getPixelColor(device, 88, 302);
8350 ok(color == 0x000000ff,
8351 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8352 color = getPixelColor(device, 92, 302);
8353 ok(color == 0x000000ff,
8354 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8356 color = getPixelColor(device, 568, 298);
8357 ok(color == 0x00ffff00,
8358 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8359 color = getPixelColor(device, 572, 298);
8360 ok(color == 0x000000ff,
8361 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8362 color = getPixelColor(device, 568, 302);
8363 ok(color == 0x000000ff,
8364 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8365 color = getPixelColor(device, 572, 302);
8366 ok(color == 0x000000ff,
8367 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8369 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8371 /* This test is pointless without those two declarations: */
8372 if((!dcl_color_2) || (!dcl_ubyte_2)) {
8373 skip("color-ubyte switching test declarations aren't supported\n");
8374 goto out;
8377 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
8378 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8379 memcpy(data, quads, sizeof(quads));
8380 hr = IDirect3DVertexBuffer9_Unlock(vb);
8381 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8382 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
8383 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8384 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8385 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
8386 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8387 memcpy(data, colors, sizeof(colors));
8388 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
8391 for(i = 0; i < 2; i++) {
8392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8395 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
8396 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8397 if(i == 0) {
8398 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
8399 } else {
8400 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
8402 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8404 hr = IDirect3DDevice9_BeginScene(device);
8405 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
8406 ub_ok = FALSE;
8407 if(SUCCEEDED(hr)) {
8408 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8409 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8410 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8411 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8412 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8413 ub_ok = SUCCEEDED(hr);
8415 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
8416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8417 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8418 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8420 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
8421 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
8422 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8423 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
8424 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8425 ub_ok = (SUCCEEDED(hr) && ub_ok);
8427 hr = IDirect3DDevice9_EndScene(device);
8428 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
8431 if(i == 0) {
8432 color = getPixelColor(device, 480, 360);
8433 ok(color == 0x00ff0000,
8434 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
8435 color = getPixelColor(device, 160, 120);
8436 ok(color == 0x00ffffff,
8437 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8438 color = getPixelColor(device, 160, 360);
8439 ok(color == 0x000000ff || !ub_ok,
8440 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8441 color = getPixelColor(device, 480, 120);
8442 ok(color == 0x000000ff || !ub_ok,
8443 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
8444 } else {
8445 color = getPixelColor(device, 480, 360);
8446 ok(color == 0x000000ff,
8447 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
8448 color = getPixelColor(device, 160, 120);
8449 ok(color == 0x00ffffff,
8450 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
8451 color = getPixelColor(device, 160, 360);
8452 ok(color == 0x00ff0000 || !ub_ok,
8453 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8454 color = getPixelColor(device, 480, 120);
8455 ok(color == 0x00ff0000 || !ub_ok,
8456 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
8458 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8461 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
8462 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8463 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
8464 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
8465 IDirect3DVertexBuffer9_Release(vb2);
8467 out:
8468 IDirect3DVertexBuffer9_Release(vb);
8469 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
8470 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
8471 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
8472 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
8473 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
8474 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
8475 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
8478 static void test_vshader_float16(void)
8480 IDirect3DVertexDeclaration9 *vdecl = NULL;
8481 IDirect3DVertexBuffer9 *buffer = NULL;
8482 IDirect3DVertexShader9 *shader;
8483 IDirect3DDevice9 *device;
8484 IDirect3D9 *d3d;
8485 ULONG refcount;
8486 D3DCAPS9 caps;
8487 DWORD color;
8488 HWND window;
8489 void *data;
8490 HRESULT hr;
8492 static const D3DVERTEXELEMENT9 decl_elements[] =
8494 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8495 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8496 D3DDECL_END()
8498 static const DWORD shader_code[] =
8500 0xfffe0101, /* vs_1_1 */
8501 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8502 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8503 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8504 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8505 0x0000ffff,
8507 static const struct vertex_float16color
8509 float x, y, z;
8510 DWORD c1, c2;
8512 quad[] =
8514 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
8515 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8516 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
8517 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
8519 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
8520 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8521 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
8522 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
8524 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
8525 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8526 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
8527 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
8529 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
8530 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8531 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
8532 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
8535 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8536 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8537 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8538 ok(!!d3d, "Failed to create a D3D object.\n");
8539 if (!(device = create_device(d3d, window, window, TRUE)))
8541 skip("Failed to create a D3D device, skipping tests.\n");
8542 goto done;
8545 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8546 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8547 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8549 skip("No vs_3_0 support, skipping tests.\n");
8550 IDirect3DDevice9_Release(device);
8551 goto done;
8554 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
8555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8557 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
8558 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
8559 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8560 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8561 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8562 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8564 hr = IDirect3DDevice9_BeginScene(device);
8565 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8566 if(SUCCEEDED(hr)) {
8567 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
8568 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8569 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
8570 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
8572 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
8574 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
8576 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8578 hr = IDirect3DDevice9_EndScene(device);
8579 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8581 color = getPixelColor(device, 480, 360);
8582 ok(color == 0x00ff0000,
8583 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8584 color = getPixelColor(device, 160, 120);
8585 ok(color == 0x00000000,
8586 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8587 color = getPixelColor(device, 160, 360);
8588 ok(color == 0x0000ff00,
8589 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8590 color = getPixelColor(device, 480, 120);
8591 ok(color == 0x000000ff,
8592 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8593 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8595 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
8596 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8598 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
8599 D3DPOOL_MANAGED, &buffer, NULL);
8600 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
8601 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
8602 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
8603 memcpy(data, quad, sizeof(quad));
8604 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8605 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
8606 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
8607 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
8609 hr = IDirect3DDevice9_BeginScene(device);
8610 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
8611 if(SUCCEEDED(hr)) {
8612 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8613 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8614 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
8615 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8616 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
8617 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8618 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
8619 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
8621 hr = IDirect3DDevice9_EndScene(device);
8622 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8625 color = getPixelColor(device, 480, 360);
8626 ok(color == 0x00ff0000,
8627 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
8628 color = getPixelColor(device, 160, 120);
8629 ok(color == 0x00000000,
8630 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
8631 color = getPixelColor(device, 160, 360);
8632 ok(color == 0x0000ff00,
8633 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
8634 color = getPixelColor(device, 480, 120);
8635 ok(color == 0x000000ff,
8636 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
8637 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8639 IDirect3DVertexDeclaration9_Release(vdecl);
8640 IDirect3DVertexShader9_Release(shader);
8641 IDirect3DVertexBuffer9_Release(buffer);
8642 refcount = IDirect3DDevice9_Release(device);
8643 ok(!refcount, "Device has %u references left.\n", refcount);
8644 done:
8645 IDirect3D9_Release(d3d);
8646 DestroyWindow(window);
8649 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
8651 D3DCAPS9 caps;
8652 IDirect3DTexture9 *texture;
8653 HRESULT hr;
8654 D3DLOCKED_RECT rect;
8655 unsigned int x, y;
8656 DWORD *dst, color;
8657 const float quad[] = {
8658 -1.0, -1.0, 0.1, -0.2, -0.2,
8659 1.0, -1.0, 0.1, 1.2, -0.2,
8660 -1.0, 1.0, 0.1, -0.2, 1.2,
8661 1.0, 1.0, 0.1, 1.2, 1.2
8663 memset(&caps, 0, sizeof(caps));
8665 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8666 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8667 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8669 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
8670 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
8671 "Card has conditional NP2 support without power of two restriction set\n");
8673 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
8675 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
8676 return;
8678 else
8680 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
8681 return;
8684 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8685 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8687 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8688 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8690 memset(&rect, 0, sizeof(rect));
8691 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
8692 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8693 for(y = 0; y < 10; y++) {
8694 for(x = 0; x < 10; x++) {
8695 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
8696 if(x == 0 || x == 9 || y == 0 || y == 9) {
8697 *dst = 0x00ff0000;
8698 } else {
8699 *dst = 0x000000ff;
8703 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8704 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8706 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8707 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8708 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8709 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8710 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8711 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8712 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8715 hr = IDirect3DDevice9_BeginScene(device);
8716 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8717 if(SUCCEEDED(hr)) {
8718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8719 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8721 hr = IDirect3DDevice9_EndScene(device);
8722 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8725 color = getPixelColor(device, 1, 1);
8726 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
8727 color = getPixelColor(device, 639, 479);
8728 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8730 color = getPixelColor(device, 135, 101);
8731 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8732 color = getPixelColor(device, 140, 101);
8733 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8734 color = getPixelColor(device, 135, 105);
8735 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8736 color = getPixelColor(device, 140, 105);
8737 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8739 color = getPixelColor(device, 135, 376);
8740 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8741 color = getPixelColor(device, 140, 376);
8742 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8743 color = getPixelColor(device, 135, 379);
8744 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8745 color = getPixelColor(device, 140, 379);
8746 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8748 color = getPixelColor(device, 500, 101);
8749 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8750 color = getPixelColor(device, 504, 101);
8751 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8752 color = getPixelColor(device, 500, 105);
8753 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8754 color = getPixelColor(device, 504, 105);
8755 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8757 color = getPixelColor(device, 500, 376);
8758 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8759 color = getPixelColor(device, 504, 376);
8760 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8761 color = getPixelColor(device, 500, 380);
8762 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8763 color = getPixelColor(device, 504, 380);
8764 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8766 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8768 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8770 IDirect3DTexture9_Release(texture);
8773 static void vface_register_test(void)
8775 IDirect3DSurface9 *surface, *backbuffer;
8776 IDirect3DVertexShader9 *vshader;
8777 IDirect3DPixelShader9 *shader;
8778 IDirect3DTexture9 *texture;
8779 IDirect3DDevice9 *device;
8780 IDirect3D9 *d3d;
8781 ULONG refcount;
8782 D3DCAPS9 caps;
8783 DWORD color;
8784 HWND window;
8785 HRESULT hr;
8787 static const DWORD shader_code[] =
8789 0xffff0300, /* ps_3_0 */
8790 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8791 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8792 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
8793 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
8794 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
8795 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8796 0x0000ffff /* END */
8798 static const DWORD vshader_code[] =
8800 0xfffe0300, /* vs_3_0 */
8801 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8802 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8803 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8804 0x0000ffff /* end */
8806 static const float quad[] =
8808 -1.0f, -1.0f, 0.1f,
8809 1.0f, -1.0f, 0.1f,
8810 -1.0f, 0.0f, 0.1f,
8812 1.0f, -1.0f, 0.1f,
8813 1.0f, 0.0f, 0.1f,
8814 -1.0f, 0.0f, 0.1f,
8816 -1.0f, 0.0f, 0.1f,
8817 -1.0f, 1.0f, 0.1f,
8818 1.0f, 0.0f, 0.1f,
8820 1.0f, 0.0f, 0.1f,
8821 -1.0f, 1.0f, 0.1f,
8822 1.0f, 1.0f, 0.1f,
8824 static const float blit[] =
8826 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
8827 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
8828 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
8829 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
8832 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8833 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8834 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8835 ok(!!d3d, "Failed to create a D3D object.\n");
8836 if (!(device = create_device(d3d, window, window, TRUE)))
8838 skip("Failed to create a D3D device, skipping tests.\n");
8839 goto done;
8842 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8843 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8844 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8846 skip("No shader model 3 support, skipping tests.\n");
8847 IDirect3DDevice9_Release(device);
8848 goto done;
8851 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8852 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8853 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8854 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8855 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8857 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8858 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8860 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
8861 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8862 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8863 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8864 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8865 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8866 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8867 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8868 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8870 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8871 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8873 hr = IDirect3DDevice9_BeginScene(device);
8874 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8875 if(SUCCEEDED(hr)) {
8876 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8877 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8878 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8879 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8880 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8882 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8883 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8884 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8886 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8888 /* Blit the texture onto the back buffer to make it visible */
8889 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8890 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
8891 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8892 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8893 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8894 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8895 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8896 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8898 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8899 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8900 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8903 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8905 hr = IDirect3DDevice9_EndScene(device);
8906 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8909 color = getPixelColor(device, 160, 360);
8910 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8911 color = getPixelColor(device, 160, 120);
8912 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8913 color = getPixelColor(device, 480, 360);
8914 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8915 color = getPixelColor(device, 480, 120);
8916 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8917 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8918 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8920 IDirect3DPixelShader9_Release(shader);
8921 IDirect3DVertexShader9_Release(vshader);
8922 IDirect3DSurface9_Release(surface);
8923 IDirect3DSurface9_Release(backbuffer);
8924 IDirect3DTexture9_Release(texture);
8925 refcount = IDirect3DDevice9_Release(device);
8926 ok(!refcount, "Device has %u references left.\n", refcount);
8927 done:
8928 IDirect3D9_Release(d3d);
8929 DestroyWindow(window);
8932 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8934 HRESULT hr;
8935 DWORD color;
8936 int i;
8937 D3DCAPS9 caps;
8938 BOOL L6V5U5_supported = FALSE;
8939 IDirect3DTexture9 *tex1, *tex2;
8940 D3DLOCKED_RECT locked_rect;
8942 static const float quad[][7] =
8944 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8945 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8946 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8947 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8950 static const D3DVERTEXELEMENT9 decl_elements[] = {
8951 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8952 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8953 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8954 D3DDECL_END()
8957 /* use asymmetric matrix to test loading */
8958 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8959 float scale, offset;
8961 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8962 IDirect3DTexture9 *texture = NULL;
8964 memset(&caps, 0, sizeof(caps));
8965 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8966 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8967 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8968 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8969 return;
8970 } else {
8971 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8972 * They report that it is not supported, but after that bump mapping works properly. So just test
8973 * if the format is generally supported, and check the BUMPENVMAP flag
8975 IDirect3D9 *d3d9;
8977 IDirect3DDevice9_GetDirect3D(device, &d3d9);
8978 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8979 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8980 L6V5U5_supported = SUCCEEDED(hr);
8981 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8982 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8983 IDirect3D9_Release(d3d9);
8984 if(FAILED(hr)) {
8985 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8986 return;
8990 /* Generate the textures */
8991 generate_bumpmap_textures(device);
8993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8994 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8996 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8997 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8998 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8999 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9000 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9002 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9003 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9004 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9005 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9006 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9007 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9009 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9010 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9011 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9012 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9013 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9014 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9016 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9017 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9019 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9020 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9022 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9023 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9026 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9027 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9028 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9029 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9031 hr = IDirect3DDevice9_BeginScene(device);
9032 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9035 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9037 hr = IDirect3DDevice9_EndScene(device);
9038 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9040 color = getPixelColor(device, 240, 60);
9041 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9042 color = getPixelColor(device, 400, 60);
9043 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9044 color = getPixelColor(device, 80, 180);
9045 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9046 color = getPixelColor(device, 560, 180);
9047 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9048 color = getPixelColor(device, 80, 300);
9049 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9050 color = getPixelColor(device, 560, 300);
9051 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9052 color = getPixelColor(device, 240, 420);
9053 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9054 color = getPixelColor(device, 400, 420);
9055 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9056 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9057 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9059 for(i = 0; i < 2; i++) {
9060 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9061 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9062 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9063 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9064 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9065 IDirect3DTexture9_Release(texture); /* To destroy it */
9068 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
9069 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
9070 goto cleanup;
9072 if(L6V5U5_supported == FALSE) {
9073 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
9074 goto cleanup;
9077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
9078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9079 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9080 * would only make this test more complicated
9082 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9083 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9084 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9085 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9087 memset(&locked_rect, 0, sizeof(locked_rect));
9088 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9089 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9090 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9091 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9092 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9094 memset(&locked_rect, 0, sizeof(locked_rect));
9095 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9096 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9097 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9098 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9099 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9101 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9102 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9103 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9104 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9106 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9107 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9108 scale = 2.0;
9109 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9110 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9111 offset = 0.1;
9112 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9113 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9115 hr = IDirect3DDevice9_BeginScene(device);
9116 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9117 if(SUCCEEDED(hr)) {
9118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9119 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9120 hr = IDirect3DDevice9_EndScene(device);
9121 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9124 color = getPixelColor(device, 320, 240);
9125 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9126 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9127 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9129 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9130 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9131 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9133 /* Check a result scale factor > 1.0 */
9134 scale = 10;
9135 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9136 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9137 offset = 10;
9138 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9139 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9141 hr = IDirect3DDevice9_BeginScene(device);
9142 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9143 if(SUCCEEDED(hr)) {
9144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9145 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9146 hr = IDirect3DDevice9_EndScene(device);
9147 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9149 color = getPixelColor(device, 320, 240);
9150 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9151 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9152 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9154 /* Check clamping in the scale factor calculation */
9155 scale = 1000;
9156 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9157 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9158 offset = -1;
9159 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9160 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9162 hr = IDirect3DDevice9_BeginScene(device);
9163 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9164 if(SUCCEEDED(hr)) {
9165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9166 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9167 hr = IDirect3DDevice9_EndScene(device);
9168 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9170 color = getPixelColor(device, 320, 240);
9171 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9173 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9175 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9176 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9177 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9178 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9180 IDirect3DTexture9_Release(tex1);
9181 IDirect3DTexture9_Release(tex2);
9183 cleanup:
9184 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9185 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9186 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
9187 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9189 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
9190 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
9191 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9194 static void stencil_cull_test(void)
9196 IDirect3DDevice9 *device;
9197 IDirect3D9 *d3d;
9198 ULONG refcount;
9199 D3DCAPS9 caps;
9200 HWND window;
9201 HRESULT hr;
9202 static const float quad1[] =
9204 -1.0, -1.0, 0.1,
9205 0.0, -1.0, 0.1,
9206 -1.0, 0.0, 0.1,
9207 0.0, 0.0, 0.1,
9209 static const float quad2[] =
9211 0.0, -1.0, 0.1,
9212 1.0, -1.0, 0.1,
9213 0.0, 0.0, 0.1,
9214 1.0, 0.0, 0.1,
9216 static const float quad3[] =
9218 0.0, 0.0, 0.1,
9219 1.0, 0.0, 0.1,
9220 0.0, 1.0, 0.1,
9221 1.0, 1.0, 0.1,
9223 static const float quad4[] =
9225 -1.0, 0.0, 0.1,
9226 0.0, 0.0, 0.1,
9227 -1.0, 1.0, 0.1,
9228 0.0, 1.0, 0.1,
9230 struct vertex painter[] =
9232 {-1.0, -1.0, 0.0, 0x00000000},
9233 { 1.0, -1.0, 0.0, 0x00000000},
9234 {-1.0, 1.0, 0.0, 0x00000000},
9235 { 1.0, 1.0, 0.0, 0x00000000},
9237 static const WORD indices_cw[] = {0, 1, 3};
9238 static const WORD indices_ccw[] = {0, 2, 3};
9239 unsigned int i;
9240 DWORD color;
9242 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9243 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9244 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9245 ok(!!d3d, "Failed to create a D3D object.\n");
9246 if (!(device = create_device(d3d, window, window, TRUE)))
9248 skip("Cannot create a device with a D24S8 stencil buffer.\n");
9249 DestroyWindow(window);
9250 IDirect3D9_Release(d3d);
9251 return;
9253 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9254 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9255 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
9257 skip("No two sided stencil support\n");
9258 goto cleanup;
9261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
9262 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9263 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9264 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
9266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9267 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
9268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9269 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
9270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
9271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
9273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
9275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
9277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
9280 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
9282 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9283 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
9284 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
9287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9291 /* First pass: Fill the stencil buffer with some values... */
9292 hr = IDirect3DDevice9_BeginScene(device);
9293 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
9294 if(SUCCEEDED(hr))
9296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9297 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9298 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9299 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9300 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9301 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9302 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
9303 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
9306 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9308 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9309 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9310 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9311 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9312 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9313 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
9314 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
9317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9318 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9319 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9320 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9321 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9322 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
9323 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
9326 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9327 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9328 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9329 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9330 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
9331 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
9332 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
9334 hr = IDirect3DDevice9_EndScene(device);
9335 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
9338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
9339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
9341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
9343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9345 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9347 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
9349 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9351 /* 2nd pass: Make the stencil values visible */
9352 hr = IDirect3DDevice9_BeginScene(device);
9353 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
9354 if(SUCCEEDED(hr))
9356 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9357 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9358 for (i = 0; i < 16; ++i)
9360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
9361 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9363 painter[0].diffuse = (i * 16); /* Creates shades of blue */
9364 painter[1].diffuse = (i * 16);
9365 painter[2].diffuse = (i * 16);
9366 painter[3].diffuse = (i * 16);
9367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
9368 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
9370 hr = IDirect3DDevice9_EndScene(device);
9371 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
9374 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9375 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9377 color = getPixelColor(device, 160, 420);
9378 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
9379 color = getPixelColor(device, 160, 300);
9380 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9382 color = getPixelColor(device, 480, 420);
9383 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
9384 color = getPixelColor(device, 480, 300);
9385 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
9387 color = getPixelColor(device, 160, 180);
9388 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
9389 color = getPixelColor(device, 160, 60);
9390 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
9392 color = getPixelColor(device, 480, 180);
9393 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
9394 color = getPixelColor(device, 480, 60);
9395 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
9397 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9398 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9400 cleanup:
9401 refcount = IDirect3DDevice9_Release(device);
9402 ok(!refcount, "Device has %u references left.\n", refcount);
9403 IDirect3D9_Release(d3d);
9404 DestroyWindow(window);
9407 static void vpos_register_test(void)
9409 IDirect3DSurface9 *surface = NULL, *backbuffer;
9410 IDirect3DPixelShader9 *shader, *shader_frac;
9411 IDirect3DVertexShader9 *vshader;
9412 IDirect3DDevice9 *device;
9413 D3DLOCKED_RECT lr;
9414 IDirect3D9 *d3d;
9415 ULONG refcount;
9416 D3DCAPS9 caps;
9417 DWORD color;
9418 HWND window;
9419 HRESULT hr;
9420 DWORD *pos;
9422 static const DWORD shader_code[] =
9424 0xffff0300, /* ps_3_0 */
9425 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9426 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
9427 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
9428 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
9429 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
9430 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
9431 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
9432 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
9433 0x0000ffff /* end */
9435 static const DWORD shader_frac_code[] =
9437 0xffff0300, /* ps_3_0 */
9438 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
9439 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
9440 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
9441 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
9442 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9443 0x0000ffff /* end */
9445 static const DWORD vshader_code[] =
9447 0xfffe0300, /* vs_3_0 */
9448 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9449 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9450 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9451 0x0000ffff /* end */
9453 static const float quad[] =
9455 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9456 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9457 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9458 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9460 float constant[4] = {1.0, 0.0, 320, 240};
9462 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9463 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9464 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9465 ok(!!d3d, "Failed to create a D3D object.\n");
9466 if (!(device = create_device(d3d, window, window, TRUE)))
9468 skip("Failed to create a D3D device, skipping tests.\n");
9469 goto done;
9472 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9473 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9474 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9476 skip("No shader model 3 support, skipping tests.\n");
9477 IDirect3DDevice9_Release(device);
9478 goto done;
9481 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9482 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9483 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9484 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9485 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9486 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9487 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
9488 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9489 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9490 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9491 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9494 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9495 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9496 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9498 hr = IDirect3DDevice9_BeginScene(device);
9499 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9500 if(SUCCEEDED(hr)) {
9501 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9502 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
9503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9504 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9505 hr = IDirect3DDevice9_EndScene(device);
9506 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9509 /* This has to be pixel exact */
9510 color = getPixelColor(device, 319, 239);
9511 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
9512 color = getPixelColor(device, 320, 239);
9513 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
9514 color = getPixelColor(device, 319, 240);
9515 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
9516 color = getPixelColor(device, 320, 240);
9517 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
9518 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9520 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
9521 &surface, NULL);
9522 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
9523 hr = IDirect3DDevice9_BeginScene(device);
9524 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9525 if(SUCCEEDED(hr)) {
9526 constant[2] = 16; constant[3] = 16;
9527 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
9528 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
9529 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9530 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9532 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9533 hr = IDirect3DDevice9_EndScene(device);
9534 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9536 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9537 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9539 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9540 color = *pos & 0x00ffffff;
9541 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
9542 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
9543 color = *pos & 0x00ffffff;
9544 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
9545 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
9546 color = *pos & 0x00ffffff;
9547 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
9548 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
9549 color = *pos & 0x00ffffff;
9550 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
9552 hr = IDirect3DSurface9_UnlockRect(surface);
9553 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9555 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
9556 * have full control over the multisampling setting inside this test
9558 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
9559 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9560 hr = IDirect3DDevice9_BeginScene(device);
9561 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
9562 if(SUCCEEDED(hr)) {
9563 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9564 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9566 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9567 hr = IDirect3DDevice9_EndScene(device);
9568 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9570 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9573 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
9574 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
9576 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
9577 color = *pos & 0x00ffffff;
9578 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
9580 hr = IDirect3DSurface9_UnlockRect(surface);
9581 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
9583 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9584 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9585 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9586 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9587 IDirect3DPixelShader9_Release(shader);
9588 IDirect3DPixelShader9_Release(shader_frac);
9589 IDirect3DVertexShader9_Release(vshader);
9590 if(surface) IDirect3DSurface9_Release(surface);
9591 IDirect3DSurface9_Release(backbuffer);
9592 refcount = IDirect3DDevice9_Release(device);
9593 ok(!refcount, "Device has %u references left.\n", refcount);
9594 done:
9595 IDirect3D9_Release(d3d);
9596 DestroyWindow(window);
9599 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
9601 D3DCOLOR color;
9603 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
9604 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9605 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9606 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9607 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9609 ++r;
9610 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
9611 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
9612 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
9613 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
9614 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
9616 return TRUE;
9619 static void pointsize_test(IDirect3DDevice9 *device)
9621 HRESULT hr;
9622 D3DCAPS9 caps;
9623 D3DMATRIX matrix;
9624 D3DMATRIX identity;
9625 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
9626 DWORD color;
9627 IDirect3DSurface9 *rt, *backbuffer;
9628 IDirect3DTexture9 *tex1, *tex2;
9629 RECT rect = {0, 0, 128, 128};
9630 D3DLOCKED_RECT lr;
9631 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
9632 0x00000000, 0x00000000};
9633 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
9634 0x00000000, 0x0000ff00};
9636 const float vertices[] = {
9637 64, 64, 0.1,
9638 128, 64, 0.1,
9639 192, 64, 0.1,
9640 256, 64, 0.1,
9641 320, 64, 0.1,
9642 384, 64, 0.1,
9643 448, 64, 0.1,
9644 512, 64, 0.1,
9647 /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */
9648 U(matrix).m[0][0] = 2.0/640.0; U(matrix).m[1][0] = 0.0; U(matrix).m[2][0] = 0.0; U(matrix).m[3][0] =-1.0;
9649 U(matrix).m[0][1] = 0.0; U(matrix).m[1][1] =-2.0/480.0; U(matrix).m[2][1] = 0.0; U(matrix).m[3][1] = 1.0;
9650 U(matrix).m[0][2] = 0.0; U(matrix).m[1][2] = 0.0; U(matrix).m[2][2] = 1.0; U(matrix).m[3][2] = 0.0;
9651 U(matrix).m[0][3] = 0.0; U(matrix).m[1][3] = 0.0; U(matrix).m[2][3] = 0.0; U(matrix).m[3][3] = 1.0;
9653 U(identity).m[0][0] = 1.0; U(identity).m[1][0] = 0.0; U(identity).m[2][0] = 0.0; U(identity).m[3][0] = 0.0;
9654 U(identity).m[0][1] = 0.0; U(identity).m[1][1] = 1.0; U(identity).m[2][1] = 0.0; U(identity).m[3][1] = 0.0;
9655 U(identity).m[0][2] = 0.0; U(identity).m[1][2] = 0.0; U(identity).m[2][2] = 1.0; U(identity).m[3][2] = 0.0;
9656 U(identity).m[0][3] = 0.0; U(identity).m[1][3] = 0.0; U(identity).m[2][3] = 0.0; U(identity).m[3][3] = 1.0;
9658 memset(&caps, 0, sizeof(caps));
9659 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9660 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9661 if(caps.MaxPointSize < 32.0) {
9662 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
9663 return;
9666 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9667 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9668 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9672 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
9673 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState 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))
9679 ptsize = 15.0;
9680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9683 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9685 ptsize = 31.0;
9686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9687 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
9689 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9691 ptsize = 30.75;
9692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
9695 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9697 if (caps.MaxPointSize >= 63.0)
9699 ptsize = 63.0;
9700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9701 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
9703 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9705 ptsize = 62.75;
9706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9707 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
9709 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9712 ptsize = 1.0;
9713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9714 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
9716 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9718 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
9719 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9720 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
9721 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
9723 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
9724 ptsize = 15.0;
9725 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9726 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9727 ptsize = 1.0;
9728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
9729 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
9731 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
9734 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9736 /* pointsize < pointsize_min < pointsize_max?
9737 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
9738 ptsize = 1.0;
9739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9740 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9741 ptsize = 15.0;
9742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
9743 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
9745 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
9748 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9750 hr = IDirect3DDevice9_EndScene(device);
9751 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
9754 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
9755 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
9756 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
9758 if (caps.MaxPointSize >= 63.0)
9760 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
9761 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
9764 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
9765 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
9766 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
9767 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
9768 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
9770 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9772 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
9773 * generates texture coordinates for the point(result: Yes, it does)
9775 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
9776 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
9777 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
9779 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
9780 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9782 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
9783 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9784 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9785 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9786 memset(&lr, 0, sizeof(lr));
9787 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9788 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9789 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9790 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9791 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9792 memset(&lr, 0, sizeof(lr));
9793 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9794 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9795 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9796 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9797 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9798 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9799 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9800 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9801 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9802 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9803 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9805 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9806 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9807 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9808 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9809 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9810 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9811 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9814 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9815 ptsize = 32.0;
9816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9817 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9819 hr = IDirect3DDevice9_BeginScene(device);
9820 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9821 if(SUCCEEDED(hr))
9823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9824 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9825 hr = IDirect3DDevice9_EndScene(device);
9826 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9829 color = getPixelColor(device, 64-4, 64-4);
9830 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9831 color = getPixelColor(device, 64-4, 64+4);
9832 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9833 color = getPixelColor(device, 64+4, 64+4);
9834 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9835 color = getPixelColor(device, 64+4, 64-4);
9836 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9837 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9839 U(matrix).m[0][0] = 1.0f / 64.0f;
9840 U(matrix).m[1][1] = -1.0f / 64.0f;
9841 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9842 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9844 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9845 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9847 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9848 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9849 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9851 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9852 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9853 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9854 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9856 hr = IDirect3DDevice9_BeginScene(device);
9857 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9858 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9859 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9860 hr = IDirect3DDevice9_EndScene(device);
9861 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9863 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9864 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9865 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9866 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9867 IDirect3DSurface9_Release(backbuffer);
9868 IDirect3DSurface9_Release(rt);
9870 color = getPixelColor(device, 64-4, 64-4);
9871 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9872 "Expected color 0x00ff0000, got 0x%08x.\n", color);
9873 color = getPixelColor(device, 64+4, 64-4);
9874 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9875 "Expected color 0x00ffff00, got 0x%08x.\n", color);
9876 color = getPixelColor(device, 64-4, 64+4);
9877 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9878 "Expected color 0x00000000, got 0x%08x.\n", color);
9879 color = getPixelColor(device, 64+4, 64+4);
9880 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9881 "Expected color 0x0000ff00, got 0x%08x.\n", color);
9883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9884 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9886 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9887 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9888 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9889 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9890 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9891 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9892 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9893 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9894 IDirect3DTexture9_Release(tex1);
9895 IDirect3DTexture9_Release(tex2);
9897 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9898 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9899 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9900 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9901 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9902 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9905 static void multiple_rendertargets_test(void)
9907 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
9908 IDirect3DPixelShader9 *ps1, *ps2;
9909 IDirect3DTexture9 *tex1, *tex2;
9910 IDirect3DVertexShader9 *vs;
9911 IDirect3DDevice9 *device;
9912 IDirect3D9 *d3d;
9913 ULONG refcount;
9914 D3DCAPS9 caps;
9915 DWORD color;
9916 HWND window;
9917 HRESULT hr;
9918 UINT i, j;
9920 static const DWORD vshader_code[] =
9922 0xfffe0300, /* vs_3_0 */
9923 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9924 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9925 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9926 0x0000ffff /* end */
9928 static const DWORD pshader_code1[] =
9930 0xffff0300, /* ps_3_0 */
9931 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9932 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9933 0x0000ffff /* end */
9935 static const DWORD pshader_code2[] =
9937 0xffff0300, /* ps_3_0 */
9938 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9939 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
9940 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
9941 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
9942 0x0000ffff /* end */
9944 static const float quad[] =
9946 -1.0f, -1.0f, 0.1f,
9947 -1.0f, 1.0f, 0.1f,
9948 1.0f, -1.0f, 0.1f,
9949 1.0f, 1.0f, 0.1f,
9951 static const float texquad[] =
9953 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9954 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9955 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9956 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9958 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9959 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9960 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9961 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9964 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9965 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9966 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9967 ok(!!d3d, "Failed to create a D3D object.\n");
9968 if (!(device = create_device(d3d, window, window, TRUE)))
9970 skip("Failed to create a D3D device, skipping tests.\n");
9971 goto done;
9974 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9975 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9976 if (caps.NumSimultaneousRTs < 2)
9978 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
9979 IDirect3DDevice9_Release(device);
9980 goto done;
9982 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9984 skip("No shader model 3 support, skipping tests.\n");
9985 IDirect3DDevice9_Release(device);
9986 goto done;
9989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
9990 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9992 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
9993 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
9994 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
9996 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
9997 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9998 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9999 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10000 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
10001 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10002 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
10003 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
10004 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
10005 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10006 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
10007 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10009 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
10010 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
10011 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
10012 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10013 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
10014 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
10016 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10017 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10018 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
10019 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10020 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
10021 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10022 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10023 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10025 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10026 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10027 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10028 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10029 color = getPixelColorFromSurface(readback, 8, 8);
10030 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10031 "Expected color 0x000000ff, got 0x%08x.\n", color);
10032 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10033 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10034 color = getPixelColorFromSurface(readback, 8, 8);
10035 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10036 "Expected color 0x000000ff, got 0x%08x.\n", color);
10038 /* Render targets not written by the pixel shader should be unmodified. */
10039 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
10040 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10041 hr = IDirect3DDevice9_BeginScene(device);
10042 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10043 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10044 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10045 hr = IDirect3DDevice9_EndScene(device);
10046 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10047 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10048 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10049 color = getPixelColorFromSurface(readback, 8, 8);
10050 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10051 "Expected color 0xff00ff00, got 0x%08x.\n", color);
10052 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10053 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10054 for (i = 6; i < 10; ++i)
10056 for (j = 6; j < 10; ++j)
10058 color = getPixelColorFromSurface(readback, j, i);
10059 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
10060 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
10064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
10065 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
10066 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
10067 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10068 color = getPixelColorFromSurface(readback, 8, 8);
10069 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10070 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10071 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
10072 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
10073 color = getPixelColorFromSurface(readback, 8, 8);
10074 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
10075 "Expected color 0x0000ff00, got 0x%08x.\n", color);
10077 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
10078 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10080 hr = IDirect3DDevice9_BeginScene(device);
10081 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
10082 if(SUCCEEDED(hr)) {
10083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10084 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
10086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10087 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10088 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10089 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
10090 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10091 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
10092 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
10093 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10094 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
10095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10096 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10097 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
10099 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10100 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
10101 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
10102 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
10104 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
10105 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
10106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
10107 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
10109 hr = IDirect3DDevice9_EndScene(device);
10110 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
10113 color = getPixelColor(device, 160, 240);
10114 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
10115 color = getPixelColor(device, 480, 240);
10116 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
10117 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10119 IDirect3DPixelShader9_Release(ps2);
10120 IDirect3DPixelShader9_Release(ps1);
10121 IDirect3DVertexShader9_Release(vs);
10122 IDirect3DTexture9_Release(tex1);
10123 IDirect3DTexture9_Release(tex2);
10124 IDirect3DSurface9_Release(surf1);
10125 IDirect3DSurface9_Release(surf2);
10126 IDirect3DSurface9_Release(backbuf);
10127 IDirect3DSurface9_Release(readback);
10128 refcount = IDirect3DDevice9_Release(device);
10129 ok(!refcount, "Device has %u references left.\n", refcount);
10130 done:
10131 IDirect3D9_Release(d3d);
10132 DestroyWindow(window);
10135 struct formats {
10136 const char *fmtName;
10137 D3DFORMAT textureFormat;
10138 DWORD resultColorBlending;
10139 DWORD resultColorNoBlending;
10142 static const struct formats test_formats[] = {
10143 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
10144 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
10145 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
10146 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
10147 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
10148 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
10149 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
10150 { NULL, 0 }
10153 static void pixelshader_blending_test(IDirect3DDevice9 *device)
10155 HRESULT hr;
10156 IDirect3DTexture9 *offscreenTexture = NULL;
10157 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
10158 IDirect3D9 *d3d = NULL;
10159 DWORD color;
10160 int fmt_index;
10162 static const float quad[][5] = {
10163 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
10164 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
10165 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
10166 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
10169 /* Quad with R=0x10, G=0x20 */
10170 static const struct vertex quad1[] = {
10171 {-1.0f, -1.0f, 0.1f, 0x80102000},
10172 {-1.0f, 1.0f, 0.1f, 0x80102000},
10173 { 1.0f, -1.0f, 0.1f, 0x80102000},
10174 { 1.0f, 1.0f, 0.1f, 0x80102000},
10177 /* Quad with R=0x20, G=0x10 */
10178 static const struct vertex quad2[] = {
10179 {-1.0f, -1.0f, 0.1f, 0x80201000},
10180 {-1.0f, 1.0f, 0.1f, 0x80201000},
10181 { 1.0f, -1.0f, 0.1f, 0x80201000},
10182 { 1.0f, 1.0f, 0.1f, 0x80201000},
10185 IDirect3DDevice9_GetDirect3D(device, &d3d);
10187 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10188 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
10189 if(!backbuffer) {
10190 goto out;
10193 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
10195 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
10197 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10198 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
10200 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
10201 continue;
10204 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
10205 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
10207 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
10208 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
10209 if(!offscreenTexture) {
10210 continue;
10213 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
10214 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
10215 if(!offscreen) {
10216 continue;
10219 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10220 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
10222 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10223 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10224 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10225 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10226 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10227 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
10228 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10229 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
10230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10231 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10233 /* Below we will draw two quads with different colors and try to blend them together.
10234 * The result color is compared with the expected outcome.
10236 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
10237 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
10238 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
10239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
10240 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
10242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
10243 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10245 /* Draw a quad using color 0x0010200 */
10246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
10247 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
10249 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10250 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10251 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
10253 /* Draw a quad using color 0x0020100 */
10254 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
10255 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
10257 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10259 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
10261 /* We don't want to blend the result on the backbuffer */
10262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
10263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10265 /* Prepare rendering the 'blended' texture quad to the backbuffer */
10266 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10267 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
10268 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
10269 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
10271 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10272 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
10274 /* This time with the texture */
10275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10276 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
10278 IDirect3DDevice9_EndScene(device);
10281 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10282 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
10284 /* Compare the color of the center quad with our expectation. */
10285 color = getPixelColor(device, 320, 240);
10286 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
10287 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
10288 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
10290 else
10292 /* No pixel shader blending is supported so expect garbage. The
10293 * type of 'garbage' depends on the driver version and OS. E.g. on
10294 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
10295 * modern ones 0x002010ff which is also what NVIDIA reports. On
10296 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
10297 color = getPixelColor(device, 320, 240);
10298 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
10299 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
10300 test_formats[fmt_index].fmtName, color);
10302 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10304 IDirect3DDevice9_SetTexture(device, 0, NULL);
10305 if(offscreenTexture) {
10306 IDirect3DTexture9_Release(offscreenTexture);
10308 if(offscreen) {
10309 IDirect3DSurface9_Release(offscreen);
10313 out:
10314 /* restore things */
10315 if(backbuffer) {
10316 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10317 IDirect3DSurface9_Release(backbuffer);
10321 static void tssargtemp_test(IDirect3DDevice9 *device)
10323 HRESULT hr;
10324 DWORD color;
10325 static const struct vertex quad[] = {
10326 {-1.0, -1.0, 0.1, 0x00ff0000},
10327 { 1.0, -1.0, 0.1, 0x00ff0000},
10328 {-1.0, 1.0, 0.1, 0x00ff0000},
10329 { 1.0, 1.0, 0.1, 0x00ff0000}
10331 D3DCAPS9 caps;
10333 memset(&caps, 0, sizeof(caps));
10334 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10335 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
10336 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
10337 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
10338 return;
10341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10344 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10345 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10346 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10347 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10349 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10350 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10351 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
10352 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10353 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
10354 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10356 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
10357 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10358 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
10359 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10360 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
10361 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10363 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
10364 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
10367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
10368 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10369 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10371 hr = IDirect3DDevice9_BeginScene(device);
10372 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
10373 if(SUCCEEDED(hr)) {
10374 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10375 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
10376 hr = IDirect3DDevice9_EndScene(device);
10377 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
10379 color = getPixelColor(device, 320, 240);
10380 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
10381 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10383 /* Set stage 1 back to default */
10384 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
10385 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10386 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10387 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10388 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10389 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10390 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
10391 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10392 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
10393 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
10396 /* Drawing Indexed Geometry with instances*/
10397 static void stream_test(void)
10399 IDirect3DVertexDeclaration9 *pDecl = NULL;
10400 IDirect3DVertexShader9 *shader = NULL;
10401 IDirect3DVertexBuffer9 *vb3 = NULL;
10402 IDirect3DVertexBuffer9 *vb2 = NULL;
10403 IDirect3DVertexBuffer9 *vb = NULL;
10404 IDirect3DIndexBuffer9 *ib = NULL;
10405 IDirect3DDevice9 *device;
10406 IDirect3D9 *d3d;
10407 ULONG refcount;
10408 D3DCAPS9 caps;
10409 DWORD color;
10410 HWND window;
10411 unsigned i;
10412 HRESULT hr;
10413 BYTE *data;
10414 DWORD ind;
10416 static const struct testdata
10418 DWORD idxVertex; /* number of instances in the first stream */
10419 DWORD idxColor; /* number of instances in the second stream */
10420 DWORD idxInstance; /* should be 1 ?? */
10421 DWORD color1; /* color 1 instance */
10422 DWORD color2; /* color 2 instance */
10423 DWORD color3; /* color 3 instance */
10424 DWORD color4; /* color 4 instance */
10425 WORD strVertex; /* specify which stream to use 0-2*/
10426 WORD strColor;
10427 WORD strInstance;
10429 testcases[]=
10431 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
10432 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
10433 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
10434 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
10435 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
10436 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
10437 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
10438 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
10439 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
10440 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
10441 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
10442 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
10443 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
10444 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
10445 #if 0
10446 /* This draws one instance on some machines, no instance on others. */
10447 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
10448 /* This case is handled in a stand alone test,
10449 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
10450 * return D3DERR_INVALIDCALL. */
10451 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
10452 #endif
10454 static const DWORD shader_code[] =
10456 0xfffe0101, /* vs_1_1 */
10457 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10458 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
10459 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
10460 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10461 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
10462 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
10463 0x0000ffff
10465 static const float quad[][3] =
10467 {-0.5f, -0.5f, 1.1f}, /*0 */
10468 {-0.5f, 0.5f, 1.1f}, /*1 */
10469 { 0.5f, -0.5f, 1.1f}, /*2 */
10470 { 0.5f, 0.5f, 1.1f}, /*3 */
10472 static const float vertcolor[][4] =
10474 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
10475 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
10476 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
10477 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
10479 /* 4 position for 4 instances */
10480 static const float instancepos[][3] =
10482 {-0.6f,-0.6f, 0.0f},
10483 { 0.6f,-0.6f, 0.0f},
10484 { 0.6f, 0.6f, 0.0f},
10485 {-0.6f, 0.6f, 0.0f},
10487 static const short indices[] = {0, 1, 2, 2, 1, 3};
10488 D3DVERTEXELEMENT9 decl[] =
10490 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10491 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10492 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10493 D3DDECL_END()
10496 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10497 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10498 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10499 ok(!!d3d, "Failed to create a D3D object.\n");
10500 if (!(device = create_device(d3d, window, window, TRUE)))
10502 skip("Failed to create a D3D device, skipping tests.\n");
10503 goto done;
10506 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10507 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10508 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10510 skip("No vs_3_0 support, skipping tests.\n");
10511 IDirect3DDevice9_Release(device);
10512 goto done;
10515 /* set the default value because it isn't done in wine? */
10516 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10517 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10519 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
10520 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
10521 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10523 /* check wrong cases */
10524 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
10525 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10526 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10527 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10528 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
10529 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10530 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10531 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10532 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
10533 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10534 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10535 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10536 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
10537 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10538 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10539 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10540 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
10541 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10542 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
10543 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
10545 /* set the default value back */
10546 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
10547 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
10549 /* create all VertexBuffers*/
10550 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
10551 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10552 if(!vb) {
10553 skip("Failed to create a vertex buffer\n");
10554 IDirect3DDevice9_Release(device);
10555 goto done;
10557 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
10558 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10559 if(!vb2) {
10560 skip("Failed to create a vertex buffer\n");
10561 goto out;
10563 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
10564 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
10565 if(!vb3) {
10566 skip("Failed to create a vertex buffer\n");
10567 goto out;
10570 /* create IndexBuffer*/
10571 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
10572 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
10573 if(!ib) {
10574 skip("Failed to create an index buffer\n");
10575 goto out;
10578 /* copy all Buffers (Vertex + Index)*/
10579 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
10580 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10581 memcpy(data, quad, sizeof(quad));
10582 hr = IDirect3DVertexBuffer9_Unlock(vb);
10583 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10584 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
10585 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10586 memcpy(data, vertcolor, sizeof(vertcolor));
10587 hr = IDirect3DVertexBuffer9_Unlock(vb2);
10588 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10589 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
10590 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
10591 memcpy(data, instancepos, sizeof(instancepos));
10592 hr = IDirect3DVertexBuffer9_Unlock(vb3);
10593 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
10594 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
10595 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
10596 memcpy(data, indices, sizeof(indices));
10597 hr = IDirect3DIndexBuffer9_Unlock(ib);
10598 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
10600 /* create VertexShader */
10601 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10602 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10603 if(!shader) {
10604 skip("Failed to create a vetex shader\n");
10605 goto out;
10608 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10609 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10611 hr = IDirect3DDevice9_SetIndices(device, ib);
10612 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
10614 /* run all tests */
10615 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
10617 struct testdata act = testcases[i];
10618 decl[0].Stream = act.strVertex;
10619 decl[1].Stream = act.strColor;
10620 decl[2].Stream = act.strInstance;
10621 /* create VertexDeclarations */
10622 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
10623 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
10625 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10626 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
10628 hr = IDirect3DDevice9_BeginScene(device);
10629 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
10630 if(SUCCEEDED(hr))
10632 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
10633 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
10635 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
10636 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10637 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
10638 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10640 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
10641 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10642 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
10643 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10645 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
10646 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10647 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
10648 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10650 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
10651 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
10652 hr = IDirect3DDevice9_EndScene(device);
10653 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
10655 /* set all StreamSource && StreamSourceFreq back to default */
10656 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
10657 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10658 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
10659 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10660 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
10661 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10662 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
10663 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10664 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
10665 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
10666 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
10667 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
10670 hr = IDirect3DVertexDeclaration9_Release(pDecl);
10671 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
10673 color = getPixelColor(device, 160, 360);
10674 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
10675 color = getPixelColor(device, 480, 360);
10676 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
10677 color = getPixelColor(device, 480, 120);
10678 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
10679 color = getPixelColor(device, 160, 120);
10680 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
10682 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10683 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
10686 out:
10687 if(vb) IDirect3DVertexBuffer9_Release(vb);
10688 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
10689 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
10690 if(ib)IDirect3DIndexBuffer9_Release(ib);
10691 if(shader)IDirect3DVertexShader9_Release(shader);
10692 refcount = IDirect3DDevice9_Release(device);
10693 ok(!refcount, "Device has %u references left.\n", refcount);
10694 done:
10695 IDirect3D9_Release(d3d);
10696 DestroyWindow(window);
10699 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
10700 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
10701 IDirect3DTexture9 *dsttex = NULL;
10702 HRESULT hr;
10703 DWORD color;
10704 D3DRECT r1 = {0, 0, 50, 50 };
10705 D3DRECT r2 = {50, 0, 100, 50 };
10706 D3DRECT r3 = {50, 50, 100, 100};
10707 D3DRECT r4 = {0, 50, 50, 100};
10708 const float quad[] = {
10709 -1.0, -1.0, 0.1, 0.0, 0.0,
10710 1.0, -1.0, 0.1, 1.0, 0.0,
10711 -1.0, 1.0, 0.1, 0.0, 1.0,
10712 1.0, 1.0, 0.1, 1.0, 1.0,
10715 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10716 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
10718 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
10719 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
10720 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
10721 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
10723 if(!src || !dsttex) {
10724 skip("One or more test resources could not be created\n");
10725 goto cleanup;
10728 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
10729 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
10731 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
10732 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10734 /* Clear the StretchRect destination for debugging */
10735 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
10736 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
10738 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10740 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
10741 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10743 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10744 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10745 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
10746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10747 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10748 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10749 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
10750 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
10752 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
10753 * the target -> texture GL blit path
10755 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
10756 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
10757 IDirect3DSurface9_Release(dst);
10759 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10760 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
10762 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
10763 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10765 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10766 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10767 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
10771 hr = IDirect3DDevice9_BeginScene(device);
10772 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
10773 if(SUCCEEDED(hr)) {
10774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10775 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
10776 hr = IDirect3DDevice9_EndScene(device);
10777 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
10780 color = getPixelColor(device, 160, 360);
10781 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
10782 color = getPixelColor(device, 480, 360);
10783 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
10784 color = getPixelColor(device, 480, 120);
10785 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
10786 color = getPixelColor(device, 160, 120);
10787 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
10788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10791 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10792 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10793 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10794 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
10796 cleanup:
10797 if(src) IDirect3DSurface9_Release(src);
10798 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
10799 if(dsttex) IDirect3DTexture9_Release(dsttex);
10802 static void texop_test(void)
10804 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
10805 IDirect3DTexture9 *texture = NULL;
10806 D3DLOCKED_RECT locked_rect;
10807 IDirect3DDevice9 *device;
10808 IDirect3D9 *d3d;
10809 D3DCOLOR color;
10810 ULONG refcount;
10811 D3DCAPS9 caps;
10812 HWND window;
10813 HRESULT hr;
10814 unsigned i;
10816 static const struct {
10817 float x, y, z;
10818 float s, t;
10819 D3DCOLOR diffuse;
10820 } quad[] = {
10821 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10822 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10823 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
10824 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
10827 static const D3DVERTEXELEMENT9 decl_elements[] = {
10828 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10829 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10830 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10831 D3DDECL_END()
10834 static const struct {
10835 D3DTEXTUREOP op;
10836 const char *name;
10837 DWORD caps_flag;
10838 D3DCOLOR result;
10839 } test_data[] = {
10840 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10841 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
10842 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
10843 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
10844 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10845 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10846 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
10847 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
10848 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
10849 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
10850 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10851 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
10852 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
10853 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10854 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
10855 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
10856 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
10857 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
10858 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
10859 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
10860 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
10861 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
10862 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
10865 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10866 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10867 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10868 ok(!!d3d, "Failed to create a D3D object.\n");
10869 if (!(device = create_device(d3d, window, window, TRUE)))
10871 skip("Failed to create a D3D device, skipping tests.\n");
10872 goto done;
10875 memset(&caps, 0, sizeof(caps));
10876 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10877 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10879 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10880 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
10881 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10882 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
10884 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10885 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10886 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10887 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10888 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
10889 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10890 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10891 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10892 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10894 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
10895 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10896 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10897 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10898 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10899 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10901 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10902 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10904 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10905 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
10907 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
10909 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10911 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10912 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10914 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
10916 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
10918 skip("tex operation %s not supported\n", test_data[i].name);
10919 continue;
10922 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
10923 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
10925 hr = IDirect3DDevice9_BeginScene(device);
10926 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10929 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10931 hr = IDirect3DDevice9_EndScene(device);
10932 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10934 color = getPixelColor(device, 320, 240);
10935 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
10936 test_data[i].name, color, test_data[i].result);
10938 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10939 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10942 IDirect3DTexture9_Release(texture);
10943 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10944 refcount = IDirect3DDevice9_Release(device);
10945 ok(!refcount, "Device has %u references left.\n", refcount);
10946 done:
10947 IDirect3D9_Release(d3d);
10948 DestroyWindow(window);
10951 static void yuv_color_test(IDirect3DDevice9 *device)
10953 HRESULT hr;
10954 IDirect3DSurface9 *surface, *target;
10955 unsigned int i;
10956 D3DLOCKED_RECT lr;
10957 IDirect3D9 *d3d;
10958 D3DCOLOR color;
10959 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
10960 D3DSURFACE_DESC desc;
10962 static const struct
10964 DWORD in;
10965 D3DFORMAT format;
10966 const char *fmt_string;
10967 D3DCOLOR left, right;
10969 test_data[] =
10971 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
10972 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
10973 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
10974 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
10975 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
10976 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
10977 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
10978 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
10979 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
10980 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
10981 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
10982 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
10983 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
10984 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
10985 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
10986 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
10987 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
10988 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
10990 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
10991 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
10992 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
10993 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
10994 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
10995 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
10996 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
10997 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
10998 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
10999 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
11000 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
11001 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
11002 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
11003 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
11004 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
11005 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
11006 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
11007 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
11010 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11011 ok(SUCCEEDED(hr), "Failed to get d3d9 interface, hr %#x.\n", hr);
11012 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11013 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
11014 hr = IDirect3DSurface9_GetDesc(target, &desc);
11015 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11017 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11019 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
11020 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
11021 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11022 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
11024 if (skip_once != test_data[i].format)
11026 skip("%s is not supported.\n", test_data[i].fmt_string);
11027 skip_once = test_data[i].format;
11029 continue;
11031 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11032 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
11034 if (skip_once != test_data[i].format)
11036 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
11037 skip_once = test_data[i].format;
11039 continue;
11042 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
11043 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
11044 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
11045 * second luminance value, resulting in an incorrect color in the right pixel. */
11046 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
11047 D3DPOOL_DEFAULT, &surface, NULL);
11048 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
11051 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11052 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
11053 ((DWORD *)lr.pBits)[0] = test_data[i].in;
11054 ((DWORD *)lr.pBits)[1] = 0x00800080;
11055 hr = IDirect3DSurface9_UnlockRect(surface);
11056 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
11058 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11059 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11060 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11061 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
11063 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11064 * although we asked for point filtering. Be careful when reading the results and use the pixel
11065 * centers. In the future we may want to add tests for the filtered pixels as well.
11067 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11068 * vastly differently, so we need a max diff of 18. */
11069 color = getPixelColor(device, 1, 240);
11070 ok(color_match(color, test_data[i].left, 18),
11071 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
11072 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
11073 color = getPixelColor(device, 318, 240);
11074 ok(color_match(color, test_data[i].right, 18),
11075 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
11076 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
11077 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11078 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11079 IDirect3DSurface9_Release(surface);
11082 IDirect3DSurface9_Release(target);
11083 IDirect3D9_Release(d3d);
11086 static void yuv_layout_test(IDirect3DDevice9 *device)
11088 HRESULT hr;
11089 IDirect3DSurface9 *surface, *target;
11090 unsigned int fmt, i, x, y;
11091 D3DFORMAT format;
11092 const char *fmt_string;
11093 D3DLOCKED_RECT lr;
11094 IDirect3D9 *d3d;
11095 D3DCOLOR color;
11096 DWORD ref_color;
11097 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
11098 UINT width = 20, height = 16;
11099 D3DCAPS9 caps;
11100 D3DSURFACE_DESC desc;
11102 static const struct
11104 DWORD color1, color2;
11105 DWORD rgb1, rgb2;
11107 test_data[] =
11109 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
11110 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
11111 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
11112 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
11113 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
11114 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
11115 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
11116 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
11119 static const struct
11121 D3DFORMAT format;
11122 const char *str;
11124 formats[] =
11126 { D3DFMT_UYVY, "D3DFMT_UYVY", },
11127 { D3DFMT_YUY2, "D3DFMT_YUY2", },
11128 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
11129 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
11132 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11133 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11134 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
11135 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
11137 skip("No NP2 texture support, skipping YUV texture layout test.\n");
11138 return;
11141 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11142 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %#x.\n", hr);
11143 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
11144 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
11145 hr = IDirect3DSurface9_GetDesc(target, &desc);
11146 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
11148 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
11150 format = formats[fmt].format;
11151 fmt_string = formats[fmt].str;
11153 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
11154 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
11155 * of drawPrimitive. */
11156 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
11157 D3DRTYPE_SURFACE, format) != D3D_OK)
11159 skip("%s is not supported.\n", fmt_string);
11160 continue;
11162 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
11163 D3DDEVTYPE_HAL, format, desc.Format)))
11165 skip("Driver cannot blit %s surfaces.\n", fmt_string);
11166 continue;
11169 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
11170 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
11172 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
11174 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
11175 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
11176 buf = lr.pBits;
11177 chroma_buf = buf + lr.Pitch * height;
11178 if (format == MAKEFOURCC('Y','V','1','2'))
11180 v_buf = chroma_buf;
11181 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
11183 /* Draw the top left quarter of the screen with color1, the rest with color2 */
11184 for (y = 0; y < height; y++)
11186 for (x = 0; x < width; x += 2)
11188 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
11189 BYTE Y = (color >> 16) & 0xff;
11190 BYTE U = (color >> 8) & 0xff;
11191 BYTE V = (color >> 0) & 0xff;
11192 if (format == D3DFMT_UYVY)
11194 buf[y * lr.Pitch + 2 * x + 0] = U;
11195 buf[y * lr.Pitch + 2 * x + 1] = Y;
11196 buf[y * lr.Pitch + 2 * x + 2] = V;
11197 buf[y * lr.Pitch + 2 * x + 3] = Y;
11199 else if (format == D3DFMT_YUY2)
11201 buf[y * lr.Pitch + 2 * x + 0] = Y;
11202 buf[y * lr.Pitch + 2 * x + 1] = U;
11203 buf[y * lr.Pitch + 2 * x + 2] = Y;
11204 buf[y * lr.Pitch + 2 * x + 3] = V;
11206 else if (format == MAKEFOURCC('Y','V','1','2'))
11208 buf[y * lr.Pitch + x + 0] = Y;
11209 buf[y * lr.Pitch + x + 1] = Y;
11210 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
11211 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
11213 else if (format == MAKEFOURCC('N','V','1','2'))
11215 buf[y * lr.Pitch + x + 0] = Y;
11216 buf[y * lr.Pitch + x + 1] = Y;
11217 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
11218 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
11222 hr = IDirect3DSurface9_UnlockRect(surface);
11223 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
11225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
11226 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
11227 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
11228 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
11230 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
11231 * although we asked for point filtering. To prevent running into precision problems, read at points
11232 * with some margin within each quadrant.
11234 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
11235 * vastly differently, so we need a max diff of 18. */
11236 for (y = 0; y < 4; y++)
11238 for (x = 0; x < 4; x++)
11240 UINT xcoord = (1 + 2 * x) * 640 / 8;
11241 UINT ycoord = (1 + 2 * y) * 480 / 8;
11242 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
11243 color = getPixelColor(device, xcoord, ycoord);
11244 ok(color_match(color, ref_color, 18),
11245 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
11246 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
11249 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11251 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
11253 IDirect3DSurface9_Release(surface);
11256 IDirect3DSurface9_Release(target);
11257 IDirect3D9_Release(d3d);
11260 static void texop_range_test(void)
11262 IDirect3DTexture9 *texture;
11263 D3DLOCKED_RECT locked_rect;
11264 IDirect3DDevice9 *device;
11265 IDirect3D9 *d3d;
11266 ULONG refcount;
11267 D3DCAPS9 caps;
11268 DWORD color;
11269 HWND window;
11270 HRESULT hr;
11272 static const struct
11274 float x, y, z;
11275 D3DCOLOR diffuse;
11277 quad[] =
11279 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11280 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11281 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
11282 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
11285 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11286 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11287 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11288 ok(!!d3d, "Failed to create a D3D object.\n");
11289 if (!(device = create_device(d3d, window, window, TRUE)))
11291 skip("Failed to create a D3D device, skipping tests.\n");
11292 goto done;
11295 /* We need ADD and SUBTRACT operations */
11296 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11297 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11298 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
11300 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
11301 IDirect3DDevice9_Release(device);
11302 goto done;
11304 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
11306 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
11307 IDirect3DDevice9_Release(device);
11308 goto done;
11311 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11312 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
11313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11314 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11315 /* Stage 1: result = diffuse(=1.0) + diffuse
11316 * stage 2: result = result - tfactor(= 0.5)
11318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11319 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11320 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11321 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11322 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
11323 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11324 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
11325 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11326 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
11327 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11328 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11329 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11330 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
11331 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11334 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
11335 hr = IDirect3DDevice9_BeginScene(device);
11336 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11337 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11338 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11339 hr = IDirect3DDevice9_EndScene(device);
11340 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11342 color = getPixelColor(device, 320, 240);
11343 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
11344 color);
11345 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11346 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11348 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11349 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11350 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11351 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11352 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
11353 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11354 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11355 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11356 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11358 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
11359 * stage 2: result = result + diffuse(1.0)
11361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11362 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11363 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11364 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11365 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11366 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11367 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
11368 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11369 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
11370 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11371 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
11372 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11373 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
11374 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11376 hr = IDirect3DDevice9_BeginScene(device);
11377 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11379 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11380 hr = IDirect3DDevice9_EndScene(device);
11381 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11383 color = getPixelColor(device, 320, 240);
11384 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
11385 color);
11386 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11387 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11389 IDirect3DTexture9_Release(texture);
11390 refcount = IDirect3DDevice9_Release(device);
11391 ok(!refcount, "Device has %u references left.\n", refcount);
11392 done:
11393 IDirect3D9_Release(d3d);
11394 DestroyWindow(window);
11397 static void alphareplicate_test(void)
11399 IDirect3DDevice9 *device;
11400 IDirect3D9 *d3d;
11401 ULONG refcount;
11402 DWORD color;
11403 HWND window;
11404 HRESULT hr;
11406 static const struct vertex quad[] =
11408 {-1.0f, -1.0f, 0.1f, 0x80ff00ff},
11409 {-1.0f, 1.0f, 0.1f, 0x80ff00ff},
11410 { 1.0f, -1.0f, 0.1f, 0x80ff00ff},
11411 { 1.0f, 1.0f, 0.1f, 0x80ff00ff},
11414 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11415 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11416 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11417 ok(!!d3d, "Failed to create a D3D object.\n");
11418 if (!(device = create_device(d3d, window, window, TRUE)))
11420 skip("Failed to create a D3D device, skipping tests.\n");
11421 goto done;
11424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11425 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11427 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11428 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11430 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11432 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
11433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11435 hr = IDirect3DDevice9_BeginScene(device);
11436 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11437 if(SUCCEEDED(hr)) {
11438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11439 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11440 hr = IDirect3DDevice9_EndScene(device);
11441 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11444 color = getPixelColor(device, 320, 240);
11445 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
11446 color);
11447 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11448 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11450 refcount = IDirect3DDevice9_Release(device);
11451 ok(!refcount, "Device has %u references left.\n", refcount);
11452 done:
11453 IDirect3D9_Release(d3d);
11454 DestroyWindow(window);
11457 static void dp3_alpha_test(void)
11459 IDirect3DDevice9 *device;
11460 IDirect3D9 *d3d;
11461 ULONG refcount;
11462 D3DCAPS9 caps;
11463 DWORD color;
11464 HWND window;
11465 HRESULT hr;
11467 static const struct vertex quad[] =
11469 {-1.0f, -1.0f, 0.1f, 0x408080c0},
11470 {-1.0f, 1.0f, 0.1f, 0x408080c0},
11471 { 1.0f, -1.0f, 0.1f, 0x408080c0},
11472 { 1.0f, 1.0f, 0.1f, 0x408080c0},
11475 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11476 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11477 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11478 ok(!!d3d, "Failed to create a D3D object.\n");
11479 if (!(device = create_device(d3d, window, window, TRUE)))
11481 skip("Failed to create a D3D device, skipping tests.\n");
11482 goto done;
11485 memset(&caps, 0, sizeof(caps));
11486 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11487 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11488 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
11490 skip("D3DTOP_DOTPRODUCT3 not supported\n");
11491 IDirect3DDevice9_Release(device);
11492 goto done;
11495 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11496 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11498 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11499 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11501 /* dp3_x4 r0, diffuse_bias, tfactor_bias
11502 * mov r0.a, diffuse.a
11503 * mov r0, r0.a
11505 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
11506 * 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
11507 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
11509 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
11510 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11511 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11512 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11513 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11514 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11515 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
11516 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11517 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
11518 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11519 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11520 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11521 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
11522 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11523 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
11524 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
11525 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
11526 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11528 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11530 hr = IDirect3DDevice9_BeginScene(device);
11531 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11532 if(SUCCEEDED(hr)) {
11533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11534 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11535 hr = IDirect3DDevice9_EndScene(device);
11536 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11539 color = getPixelColor(device, 320, 240);
11540 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
11541 color);
11542 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11543 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11545 refcount = IDirect3DDevice9_Release(device);
11546 ok(!refcount, "Device has %u references left.\n", refcount);
11547 done:
11548 IDirect3D9_Release(d3d);
11549 DestroyWindow(window);
11552 static void zwriteenable_test(void)
11554 IDirect3DDevice9 *device;
11555 IDirect3D9 *d3d;
11556 D3DCOLOR color;
11557 ULONG refcount;
11558 HWND window;
11559 HRESULT hr;
11561 static const struct vertex quad1[] =
11563 {-1.0f, -1.0f, 0.1f, 0x00ff0000},
11564 {-1.0f, 1.0f, 0.1f, 0x00ff0000},
11565 { 1.0f, -1.0f, 0.1f, 0x00ff0000},
11566 { 1.0f, 1.0f, 0.1f, 0x00ff0000},
11568 static const struct vertex quad2[] =
11570 {-1.0f, -1.0f, 0.9f, 0x0000ff00},
11571 {-1.0f, 1.0f, 0.9f, 0x0000ff00},
11572 { 1.0f, -1.0f, 0.9f, 0x0000ff00},
11573 { 1.0f, 1.0f, 0.9f, 0x0000ff00},
11576 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11577 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11578 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11579 ok(!!d3d, "Failed to create a D3D object.\n");
11580 if (!(device = create_device(d3d, window, window, TRUE)))
11582 skip("Failed to create a D3D device, skipping tests.\n");
11583 goto done;
11586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
11587 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11589 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11590 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11592 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11596 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11597 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11598 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11600 hr = IDirect3DDevice9_BeginScene(device);
11601 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11602 if(SUCCEEDED(hr)) {
11603 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
11604 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
11605 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
11606 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
11607 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
11608 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
11610 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11611 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11613 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11614 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11615 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11617 hr = IDirect3DDevice9_EndScene(device);
11618 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11621 color = getPixelColor(device, 320, 240);
11622 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
11623 color);
11624 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11625 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11627 refcount = IDirect3DDevice9_Release(device);
11628 ok(!refcount, "Device has %u references left.\n", refcount);
11629 done:
11630 IDirect3D9_Release(d3d);
11631 DestroyWindow(window);
11634 static void alphatest_test(void)
11636 #define ALPHATEST_PASSED 0x0000ff00
11637 #define ALPHATEST_FAILED 0x00ff0000
11638 IDirect3DDevice9 *device;
11639 unsigned int i, j;
11640 IDirect3D9 *d3d;
11641 D3DCOLOR color;
11642 ULONG refcount;
11643 D3DCAPS9 caps;
11644 HWND window;
11645 HRESULT hr;
11647 static const struct
11649 D3DCMPFUNC func;
11650 D3DCOLOR color_less;
11651 D3DCOLOR color_equal;
11652 D3DCOLOR color_greater;
11654 testdata[] =
11656 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11657 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11658 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11659 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11660 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11661 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11662 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11663 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11665 static const struct vertex quad[] =
11667 {-1.0f, -1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11668 {-1.0f, 1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11669 { 1.0f, -1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11670 { 1.0f, 1.0f, 0.1f, ALPHATEST_PASSED | 0x80000000},
11673 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11674 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11675 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11676 ok(!!d3d, "Failed to create a D3D object.\n");
11677 if (!(device = create_device(d3d, window, window, TRUE)))
11679 skip("Failed to create a D3D device, skipping tests.\n");
11680 goto done;
11683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11684 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11687 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
11689 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11690 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11691 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11693 for (j = 0; j < 2; ++j)
11695 if (j == 1)
11697 /* Try a pixel shader instead of fixed function. The wined3d code
11698 * may emulate the alpha test either for performance reasons
11699 * (floating point RTs) or to work around driver bugs (GeForce
11700 * 7x00 cards on MacOS). There may be a different codepath for ffp
11701 * and shader in this case, and the test should cover both. */
11702 IDirect3DPixelShader9 *ps;
11703 static const DWORD shader_code[] =
11705 0xffff0101, /* ps_1_1 */
11706 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11707 0x0000ffff /* end */
11709 memset(&caps, 0, sizeof(caps));
11710 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11711 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
11712 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
11713 break;
11716 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
11717 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
11718 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
11720 IDirect3DPixelShader9_Release(ps);
11723 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
11724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
11725 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11727 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11728 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
11730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11731 hr = IDirect3DDevice9_BeginScene(device);
11732 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11733 if(SUCCEEDED(hr)) {
11734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11735 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11736 hr = IDirect3DDevice9_EndScene(device);
11737 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11739 color = getPixelColor(device, 320, 240);
11740 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
11741 color, testdata[i].color_less, testdata[i].func);
11742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11743 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
11748 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11749 hr = IDirect3DDevice9_BeginScene(device);
11750 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11751 if(SUCCEEDED(hr)) {
11752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11753 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11754 hr = IDirect3DDevice9_EndScene(device);
11755 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11757 color = getPixelColor(device, 320, 240);
11758 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
11759 color, testdata[i].color_equal, testdata[i].func);
11760 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11761 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11763 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
11764 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
11766 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
11767 hr = IDirect3DDevice9_BeginScene(device);
11768 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
11769 if(SUCCEEDED(hr)) {
11770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11771 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11772 hr = IDirect3DDevice9_EndScene(device);
11773 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11775 color = getPixelColor(device, 320, 240);
11776 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
11777 color, testdata[i].color_greater, testdata[i].func);
11778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11779 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
11783 refcount = IDirect3DDevice9_Release(device);
11784 ok(!refcount, "Device has %u references left.\n", refcount);
11785 done:
11786 IDirect3D9_Release(d3d);
11787 DestroyWindow(window);
11790 static void sincos_test(void)
11792 IDirect3DVertexShader9 *sin_shader, *cos_shader;
11793 IDirect3DDevice9 *device;
11794 struct vec3 data[1280];
11795 IDirect3D9 *d3d;
11796 unsigned int i;
11797 ULONG refcount;
11798 D3DCAPS9 caps;
11799 HWND window;
11800 HRESULT hr;
11802 static const DWORD sin_shader_code[] =
11804 0xfffe0200, /* vs_2_0 */
11805 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11806 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
11807 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
11808 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
11809 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
11810 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
11811 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
11812 0x0000ffff /* end */
11814 static const DWORD cos_shader_code[] =
11816 0xfffe0200, /* vs_2_0 */
11817 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11818 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
11819 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
11820 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
11821 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
11822 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
11823 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
11824 0x0000ffff /* end */
11826 static const float sincosc1[4] = {D3DSINCOSCONST1};
11827 static const float sincosc2[4] = {D3DSINCOSCONST2};
11829 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11830 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11831 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11832 ok(!!d3d, "Failed to create a D3D object.\n");
11833 if (!(device = create_device(d3d, window, window, TRUE)))
11835 skip("Failed to create a D3D device, skipping tests.\n");
11836 goto done;
11839 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11840 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11841 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11843 skip("No vs_2_0 support, skipping tests.\n");
11844 IDirect3DDevice9_Release(device);
11845 goto done;
11848 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11849 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11851 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
11852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11853 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
11854 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11855 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11856 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
11857 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
11858 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
11859 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
11860 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
11862 /* Generate a point from -1 to 1 every 0.5 pixels */
11863 for(i = 0; i < 1280; i++) {
11864 data[i].x = (-640.0 + i) / 640.0;
11865 data[i].y = 0.0;
11866 data[i].z = 0.1;
11869 hr = IDirect3DDevice9_BeginScene(device);
11870 if(SUCCEEDED(hr)) {
11871 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
11872 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
11873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
11874 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
11876 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
11877 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
11878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
11879 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
11881 hr = IDirect3DDevice9_EndScene(device);
11882 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
11884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11885 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
11886 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
11888 IDirect3DVertexShader9_Release(sin_shader);
11889 IDirect3DVertexShader9_Release(cos_shader);
11890 refcount = IDirect3DDevice9_Release(device);
11891 ok(!refcount, "Device has %u references left.\n", refcount);
11892 done:
11893 IDirect3D9_Release(d3d);
11894 DestroyWindow(window);
11897 static void loop_index_test(void)
11899 IDirect3DVertexShader9 *shader;
11900 IDirect3DDevice9 *device;
11901 IDirect3D9 *d3d;
11902 float values[4];
11903 ULONG refcount;
11904 D3DCAPS9 caps;
11905 DWORD color;
11906 HWND window;
11907 HRESULT hr;
11909 static const DWORD shader_code[] =
11911 0xfffe0200, /* vs_2_0 */
11912 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11913 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
11914 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
11915 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
11916 0x0000001d, /* endloop */
11917 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11918 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
11919 0x0000ffff /* END */
11921 static const float quad[] =
11923 -1.0f, -1.0f, 0.1f,
11924 -1.0f, 1.0f, 0.1f,
11925 1.0f, -1.0f, 0.1f,
11926 1.0f, 1.0f, 0.1f,
11928 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
11929 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
11930 static const int i0[4] = {2, 10, -3, 0};
11932 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11933 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11934 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11935 ok(!!d3d, "Failed to create a D3D object.\n");
11936 if (!(device = create_device(d3d, window, window, TRUE)))
11938 skip("Failed to create a D3D device, skipping tests.\n");
11939 goto done;
11942 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11943 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11944 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11946 skip("No vs_2_0 support, skipping tests.\n");
11947 IDirect3DDevice9_Release(device);
11948 goto done;
11951 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11952 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
11953 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11954 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
11955 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11956 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11957 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
11958 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
11960 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
11961 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11962 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
11963 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11964 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
11965 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11966 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
11967 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11968 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
11969 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11970 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
11971 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11972 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
11973 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11974 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
11975 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11976 values[0] = 1.0;
11977 values[1] = 1.0;
11978 values[2] = 0.0;
11979 values[3] = 0.0;
11980 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
11981 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11982 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
11983 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11984 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
11985 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11986 values[0] = -1.0;
11987 values[1] = 0.0;
11988 values[2] = 0.0;
11989 values[3] = 0.0;
11990 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
11991 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11992 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
11993 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11994 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
11995 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11996 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
11997 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
11998 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
11999 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
12001 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
12002 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
12004 hr = IDirect3DDevice9_BeginScene(device);
12005 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
12006 if(SUCCEEDED(hr))
12008 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12009 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
12010 hr = IDirect3DDevice9_EndScene(device);
12011 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
12013 color = getPixelColor(device, 320, 240);
12014 ok(color_match(color, 0x0000ff00, 1),
12015 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
12016 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12017 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12019 IDirect3DVertexShader9_Release(shader);
12020 refcount = IDirect3DDevice9_Release(device);
12021 ok(!refcount, "Device has %u references left.\n", refcount);
12022 done:
12023 IDirect3D9_Release(d3d);
12024 DestroyWindow(window);
12027 static void sgn_test(void)
12029 IDirect3DVertexShader9 *shader;
12030 IDirect3DDevice9 *device;
12031 IDirect3D9 *d3d;
12032 ULONG refcount;
12033 D3DCAPS9 caps;
12034 DWORD color;
12035 HWND window;
12036 HRESULT hr;
12038 static const DWORD shader_code[] =
12040 0xfffe0200, /* vs_2_0 */
12041 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
12042 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
12043 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
12044 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12045 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
12046 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
12047 0x0000ffff /* end */
12049 static const float quad[] =
12051 -1.0f, -1.0f, 0.1f,
12052 -1.0f, 1.0f, 0.1f,
12053 1.0f, -1.0f, 0.1f,
12054 1.0f, 1.0f, 0.1f,
12057 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12058 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12059 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12060 ok(!!d3d, "Failed to create a D3D object.\n");
12061 if (!(device = create_device(d3d, window, window, TRUE)))
12063 skip("Failed to create a D3D device, skipping tests.\n");
12064 goto done;
12067 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12068 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12069 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12071 skip("No vs_2_0 support, skipping tests.\n");
12072 IDirect3DDevice9_Release(device);
12073 goto done;
12076 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
12077 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
12078 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12079 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
12080 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12081 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12083 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12085 hr = IDirect3DDevice9_BeginScene(device);
12086 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
12087 if(SUCCEEDED(hr))
12089 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12090 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
12091 hr = IDirect3DDevice9_EndScene(device);
12092 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
12094 color = getPixelColor(device, 320, 240);
12095 ok(color_match(color, 0x008000ff, 1),
12096 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
12097 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12098 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12100 IDirect3DVertexShader9_Release(shader);
12101 refcount = IDirect3DDevice9_Release(device);
12102 ok(!refcount, "Device has %u references left.\n", refcount);
12103 done:
12104 IDirect3D9_Release(d3d);
12105 DestroyWindow(window);
12108 static void viewport_test(void)
12110 IDirect3DDevice9 *device;
12111 BOOL draw_failed = TRUE;
12112 D3DVIEWPORT9 vp;
12113 IDirect3D9 *d3d;
12114 ULONG refcount;
12115 DWORD color;
12116 HWND window;
12117 HRESULT hr;
12119 static const float quad[] =
12121 -0.5f, -0.5f, 0.1f,
12122 -0.5f, 0.5f, 0.1f,
12123 0.5f, -0.5f, 0.1f,
12124 0.5f, 0.5f, 0.1f,
12127 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12128 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12129 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12130 ok(!!d3d, "Failed to create a D3D object.\n");
12131 if (!(device = create_device(d3d, window, window, TRUE)))
12133 skip("Failed to create a D3D device, skipping tests.\n");
12134 goto done;
12137 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
12138 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
12140 /* Test a viewport with Width and Height bigger than the surface dimensions
12142 * TODO: Test Width < surface.width, but X + Width > surface.width
12143 * TODO: Test Width < surface.width, what happens with the height?
12145 * The expected behavior is that the viewport behaves like the "default"
12146 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
12147 * MinZ = 0.0, MaxZ = 1.0.
12149 * Starting with Windows 7 the behavior among driver versions is not
12150 * consistent. The SetViewport call is accepted on all drivers. Some
12151 * drivers(older nvidia ones) refuse to draw and return an error. Newer
12152 * nvidia drivers draw, but use the actual values in the viewport and only
12153 * display the upper left part on the surface.
12155 memset(&vp, 0, sizeof(vp));
12156 vp.X = 0;
12157 vp.Y = 0;
12158 vp.Width = 10000;
12159 vp.Height = 10000;
12160 vp.MinZ = 0.0;
12161 vp.MaxZ = 0.0;
12162 hr = IDirect3DDevice9_SetViewport(device, &vp);
12163 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
12165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12166 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12168 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12169 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
12170 hr = IDirect3DDevice9_BeginScene(device);
12171 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
12172 if(SUCCEEDED(hr))
12174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12175 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
12176 draw_failed = FAILED(hr);
12177 hr = IDirect3DDevice9_EndScene(device);
12178 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
12181 if(!draw_failed)
12183 color = getPixelColor(device, 158, 118);
12184 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
12185 color = getPixelColor(device, 162, 118);
12186 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
12187 color = getPixelColor(device, 158, 122);
12188 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
12189 color = getPixelColor(device, 162, 122);
12190 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
12192 color = getPixelColor(device, 478, 358);
12193 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
12194 color = getPixelColor(device, 482, 358);
12195 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
12196 color = getPixelColor(device, 478, 362);
12197 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
12198 color = getPixelColor(device, 482, 362);
12199 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
12202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12203 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12205 refcount = IDirect3DDevice9_Release(device);
12206 ok(!refcount, "Device has %u references left.\n", refcount);
12207 done:
12208 IDirect3D9_Release(d3d);
12209 DestroyWindow(window);
12212 /* This test tests depth clamping / clipping behaviour:
12213 * - With software vertex processing, depth values are clamped to the
12214 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
12215 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
12216 * same as regular vertices here.
12217 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
12218 * Normal vertices are always clipped. Pretransformed vertices are
12219 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
12220 * - The viewport's MinZ/MaxZ is irrelevant for this.
12222 static void depth_clamp_test(IDirect3DDevice9 *device)
12224 const struct tvertex quad1[] =
12226 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
12227 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
12228 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
12229 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
12231 const struct tvertex quad2[] =
12233 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
12234 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
12235 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
12236 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
12238 const struct tvertex quad3[] =
12240 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
12241 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
12242 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
12243 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
12245 const struct tvertex quad4[] =
12247 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
12248 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
12249 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
12250 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
12252 const struct vertex quad5[] =
12254 { -0.5f, 0.5f, 10.0f, 0xff14f914},
12255 { 0.5f, 0.5f, 10.0f, 0xff14f914},
12256 { -0.5f, -0.5f, 10.0f, 0xff14f914},
12257 { 0.5f, -0.5f, 10.0f, 0xff14f914},
12259 const struct vertex quad6[] =
12261 { -1.0f, 0.5f, 10.0f, 0xfff91414},
12262 { 1.0f, 0.5f, 10.0f, 0xfff91414},
12263 { -1.0f, 0.25f, 10.0f, 0xfff91414},
12264 { 1.0f, 0.25f, 10.0f, 0xfff91414},
12267 D3DVIEWPORT9 vp;
12268 D3DCOLOR color;
12269 D3DCAPS9 caps;
12270 HRESULT hr;
12272 vp.X = 0;
12273 vp.Y = 0;
12274 vp.Width = 640;
12275 vp.Height = 480;
12276 vp.MinZ = 0.0;
12277 vp.MaxZ = 7.5;
12279 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12280 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12282 hr = IDirect3DDevice9_SetViewport(device, &vp);
12283 if(FAILED(hr))
12285 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
12286 * the tests because the 7.5 is just intended to show that it doesn't have
12287 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
12288 * viewport and continue.
12290 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
12291 vp.MaxZ = 1.0;
12292 hr = IDirect3DDevice9_SetViewport(device, &vp);
12294 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12296 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
12297 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
12300 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12302 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12304 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12306 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12308 hr = IDirect3DDevice9_BeginScene(device);
12309 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12311 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
12312 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12315 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12317 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12320 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12322 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12323 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
12325 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
12328 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12330 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12331 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12333 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
12334 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
12337 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12339 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
12340 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12342 hr = IDirect3DDevice9_EndScene(device);
12343 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12345 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
12347 color = getPixelColor(device, 75, 75);
12348 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12349 color = getPixelColor(device, 150, 150);
12350 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12351 color = getPixelColor(device, 320, 240);
12352 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12353 color = getPixelColor(device, 320, 330);
12354 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12355 color = getPixelColor(device, 320, 330);
12356 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
12358 else
12360 color = getPixelColor(device, 75, 75);
12361 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
12362 color = getPixelColor(device, 150, 150);
12363 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
12364 color = getPixelColor(device, 320, 240);
12365 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
12366 color = getPixelColor(device, 320, 330);
12367 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12368 color = getPixelColor(device, 320, 330);
12369 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12372 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12373 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12375 vp.MinZ = 0.0;
12376 vp.MaxZ = 1.0;
12377 hr = IDirect3DDevice9_SetViewport(device, &vp);
12378 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12381 static void depth_bounds_test(void)
12383 const struct tvertex quad1[] =
12385 { 0, 0, 0.0f, 1, 0xfff9e814},
12386 { 640, 0, 0.0f, 1, 0xfff9e814},
12387 { 0, 480, 1.0f, 1, 0xfff9e814},
12388 { 640, 480, 1.0f, 1, 0xfff9e814},
12390 const struct tvertex quad2[] =
12392 { 0, 0, 0.6f, 1, 0xff002b7f},
12393 { 640, 0, 0.6f, 1, 0xff002b7f},
12394 { 0, 480, 0.6f, 1, 0xff002b7f},
12395 { 640, 480, 0.6f, 1, 0xff002b7f},
12397 const struct tvertex quad3[] =
12399 { 0, 100, 0.6f, 1, 0xfff91414},
12400 { 640, 100, 0.6f, 1, 0xfff91414},
12401 { 0, 160, 0.6f, 1, 0xfff91414},
12402 { 640, 160, 0.6f, 1, 0xfff91414},
12405 union {
12406 DWORD d;
12407 float f;
12408 } tmpvalue;
12410 IDirect3DSurface9 *offscreen_surface = NULL;
12411 IDirect3DDevice9 *device;
12412 IDirect3D9 *d3d;
12413 D3DCOLOR color;
12414 ULONG refcount;
12415 HWND window;
12416 HRESULT hr;
12418 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12419 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12420 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12421 ok(!!d3d, "Failed to create a D3D object.\n");
12422 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12423 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
12425 skip("No NVDB (depth bounds test) support, skipping tests.\n");
12426 goto done;
12428 if (!(device = create_device(d3d, window, window, TRUE)))
12430 skip("Failed to create a D3D device, skipping tests.\n");
12431 goto done;
12434 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
12435 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
12436 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
12437 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
12439 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
12440 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12443 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
12445 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12447 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
12449 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12452 hr = IDirect3DDevice9_BeginScene(device);
12453 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12455 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
12456 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12459 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
12462 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12464 tmpvalue.f = 0.625;
12465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
12466 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12468 tmpvalue.f = 0.75;
12469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
12470 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12473 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12475 tmpvalue.f = 0.75;
12476 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
12477 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12480 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
12483 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12485 hr = IDirect3DDevice9_EndScene(device);
12486 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12488 color = getPixelColor(device, 150, 130);
12489 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12490 color = getPixelColor(device, 150, 200);
12491 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12492 color = getPixelColor(device, 150, 300-5);
12493 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12494 color = getPixelColor(device, 150, 300+5);
12495 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
12496 color = getPixelColor(device, 150, 330);
12497 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
12498 color = getPixelColor(device, 150, 360-5);
12499 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
12500 color = getPixelColor(device, 150, 360+5);
12501 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
12503 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12504 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12505 refcount = IDirect3DDevice9_Release(device);
12506 ok(!refcount, "Device has %u references left.\n", refcount);
12507 done:
12508 IDirect3D9_Release(d3d);
12509 DestroyWindow(window);
12512 static void depth_buffer_test(void)
12514 static const struct vertex quad1[] =
12516 { -1.0, 1.0, 0.33f, 0xff00ff00},
12517 { 1.0, 1.0, 0.33f, 0xff00ff00},
12518 { -1.0, -1.0, 0.33f, 0xff00ff00},
12519 { 1.0, -1.0, 0.33f, 0xff00ff00},
12521 static const struct vertex quad2[] =
12523 { -1.0, 1.0, 0.50f, 0xffff00ff},
12524 { 1.0, 1.0, 0.50f, 0xffff00ff},
12525 { -1.0, -1.0, 0.50f, 0xffff00ff},
12526 { 1.0, -1.0, 0.50f, 0xffff00ff},
12528 static const struct vertex quad3[] =
12530 { -1.0, 1.0, 0.66f, 0xffff0000},
12531 { 1.0, 1.0, 0.66f, 0xffff0000},
12532 { -1.0, -1.0, 0.66f, 0xffff0000},
12533 { 1.0, -1.0, 0.66f, 0xffff0000},
12535 static const DWORD expected_colors[4][4] =
12537 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12538 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12539 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
12540 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12543 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
12544 IDirect3DDevice9 *device;
12545 unsigned int i, j;
12546 D3DVIEWPORT9 vp;
12547 IDirect3D9 *d3d;
12548 D3DCOLOR color;
12549 ULONG refcount;
12550 HWND window;
12551 HRESULT hr;
12553 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12554 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12555 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12556 ok(!!d3d, "Failed to create a D3D object.\n");
12557 if (!(device = create_device(d3d, window, window, TRUE)))
12559 skip("Failed to create a D3D device, skipping tests.\n");
12560 goto done;
12563 vp.X = 0;
12564 vp.Y = 0;
12565 vp.Width = 640;
12566 vp.Height = 480;
12567 vp.MinZ = 0.0;
12568 vp.MaxZ = 1.0;
12570 hr = IDirect3DDevice9_SetViewport(device, &vp);
12571 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12574 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12576 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12578 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12580 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12581 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12582 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12584 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12585 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12586 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
12587 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
12588 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12589 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
12590 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
12591 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12592 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12593 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
12594 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12596 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
12597 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12598 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
12599 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12601 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12602 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12603 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12604 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12606 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
12607 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12608 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
12609 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12611 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
12612 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12613 hr = IDirect3DDevice9_BeginScene(device);
12614 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12615 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12616 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12617 hr = IDirect3DDevice9_EndScene(device);
12618 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12620 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12621 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12624 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12626 hr = IDirect3DDevice9_BeginScene(device);
12627 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12628 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12629 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
12631 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12632 hr = IDirect3DDevice9_EndScene(device);
12633 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12635 for (i = 0; i < 4; ++i)
12637 for (j = 0; j < 4; ++j)
12639 unsigned int x = 80 * ((2 * j) + 1);
12640 unsigned int y = 60 * ((2 * i) + 1);
12641 color = getPixelColor(device, x, y);
12642 ok(color_match(color, expected_colors[i][j], 0),
12643 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
12647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12648 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12650 IDirect3DSurface9_Release(backbuffer);
12651 IDirect3DSurface9_Release(rt3);
12652 IDirect3DSurface9_Release(rt2);
12653 IDirect3DSurface9_Release(rt1);
12654 refcount = IDirect3DDevice9_Release(device);
12655 ok(!refcount, "Device has %u references left.\n", refcount);
12656 done:
12657 IDirect3D9_Release(d3d);
12658 DestroyWindow(window);
12661 /* Test that partial depth copies work the way they're supposed to. The clear
12662 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
12663 * the following draw should only copy back the part that was modified. */
12664 static void depth_buffer2_test(void)
12666 static const struct vertex quad[] =
12668 { -1.0, 1.0, 0.66f, 0xffff0000},
12669 { 1.0, 1.0, 0.66f, 0xffff0000},
12670 { -1.0, -1.0, 0.66f, 0xffff0000},
12671 { 1.0, -1.0, 0.66f, 0xffff0000},
12674 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
12675 IDirect3DDevice9 *device;
12676 unsigned int i, j;
12677 D3DVIEWPORT9 vp;
12678 IDirect3D9 *d3d;
12679 D3DCOLOR color;
12680 ULONG refcount;
12681 HWND window;
12682 HRESULT hr;
12684 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12685 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12686 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12687 ok(!!d3d, "Failed to create a D3D object.\n");
12688 if (!(device = create_device(d3d, window, window, TRUE)))
12690 skip("Failed to create a D3D device, skipping tests.\n");
12691 goto done;
12694 vp.X = 0;
12695 vp.Y = 0;
12696 vp.Width = 640;
12697 vp.Height = 480;
12698 vp.MinZ = 0.0;
12699 vp.MaxZ = 1.0;
12701 hr = IDirect3DDevice9_SetViewport(device, &vp);
12702 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12705 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12707 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12709 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12711 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12712 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12713 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12715 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
12716 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
12717 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12718 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
12719 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
12720 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
12721 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12722 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12724 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
12725 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12726 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12727 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12729 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12730 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12731 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
12732 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12734 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
12735 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12736 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
12737 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12739 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12740 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
12742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12743 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12745 hr = IDirect3DDevice9_BeginScene(device);
12746 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12748 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12749 hr = IDirect3DDevice9_EndScene(device);
12750 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12752 for (i = 0; i < 4; ++i)
12754 for (j = 0; j < 4; ++j)
12756 unsigned int x = 80 * ((2 * j) + 1);
12757 unsigned int y = 60 * ((2 * i) + 1);
12758 color = getPixelColor(device, x, y);
12759 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
12760 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
12764 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12765 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12767 IDirect3DSurface9_Release(backbuffer);
12768 IDirect3DSurface9_Release(rt2);
12769 IDirect3DSurface9_Release(rt1);
12770 refcount = IDirect3DDevice9_Release(device);
12771 ok(!refcount, "Device has %u references left.\n", refcount);
12772 done:
12773 IDirect3D9_Release(d3d);
12774 DestroyWindow(window);
12777 static void depth_blit_test(void)
12779 static const struct vertex quad1[] =
12781 { -1.0, 1.0, 0.33f, 0xff00ff00},
12782 { 1.0, 1.0, 0.33f, 0xff00ff00},
12783 { -1.0, -1.0, 0.33f, 0xff00ff00},
12784 { 1.0, -1.0, 0.33f, 0xff00ff00},
12786 static const struct vertex quad2[] =
12788 { -1.0, 1.0, 0.66f, 0xff0000ff},
12789 { 1.0, 1.0, 0.66f, 0xff0000ff},
12790 { -1.0, -1.0, 0.66f, 0xff0000ff},
12791 { 1.0, -1.0, 0.66f, 0xff0000ff},
12793 static const DWORD expected_colors[4][4] =
12795 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12796 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
12797 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
12798 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
12801 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
12802 IDirect3DDevice9 *device;
12803 RECT src_rect, dst_rect;
12804 unsigned int i, j;
12805 D3DVIEWPORT9 vp;
12806 IDirect3D9 *d3d;
12807 D3DCOLOR color;
12808 ULONG refcount;
12809 HWND window;
12810 HRESULT hr;
12812 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12813 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12814 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12815 ok(!!d3d, "Failed to create a D3D object.\n");
12816 if (!(device = create_device(d3d, window, window, TRUE)))
12818 skip("Failed to create a D3D device, skipping tests.\n");
12819 goto done;
12822 vp.X = 0;
12823 vp.Y = 0;
12824 vp.Width = 640;
12825 vp.Height = 480;
12826 vp.MinZ = 0.0;
12827 vp.MaxZ = 1.0;
12829 hr = IDirect3DDevice9_SetViewport(device, &vp);
12830 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
12832 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12833 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
12834 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
12835 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
12836 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
12837 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
12838 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
12839 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12840 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
12841 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
12843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12844 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12846 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12848 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12849 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12850 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
12853 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12854 SetRect(&dst_rect, 0, 0, 480, 360);
12855 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
12856 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12857 SetRect(&dst_rect, 0, 0, 320, 240);
12858 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
12859 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12861 /* Partial blit. */
12862 SetRect(&src_rect, 0, 0, 320, 240);
12863 SetRect(&dst_rect, 0, 0, 320, 240);
12864 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
12865 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12866 /* Flipped. */
12867 SetRect(&src_rect, 0, 0, 640, 480);
12868 SetRect(&dst_rect, 0, 480, 640, 0);
12869 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
12870 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12871 /* Full, explicit. */
12872 SetRect(&src_rect, 0, 0, 640, 480);
12873 SetRect(&dst_rect, 0, 0, 640, 480);
12874 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
12875 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
12876 /* Filtered blit. */
12877 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
12878 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
12879 /* Depth -> color blit.*/
12880 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
12881 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12882 IDirect3DSurface9_Release(backbuffer);
12883 /* Full surface, different sizes */
12884 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
12885 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12886 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
12887 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
12889 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
12890 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
12891 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
12892 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12893 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
12894 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
12896 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
12897 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12898 hr = IDirect3DDevice9_BeginScene(device);
12899 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12900 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12901 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12903 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12904 hr = IDirect3DDevice9_EndScene(device);
12905 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12907 for (i = 0; i < 4; ++i)
12909 for (j = 0; j < 4; ++j)
12911 unsigned int x = 80 * ((2 * j) + 1);
12912 unsigned int y = 60 * ((2 * i) + 1);
12913 color = getPixelColor(device, x, y);
12914 ok(color_match(color, expected_colors[i][j], 0),
12915 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
12919 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12920 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
12922 IDirect3DSurface9_Release(ds3);
12923 IDirect3DSurface9_Release(ds2);
12924 IDirect3DSurface9_Release(ds1);
12925 refcount = IDirect3DDevice9_Release(device);
12926 ok(!refcount, "Device has %u references left.\n", refcount);
12927 done:
12928 IDirect3D9_Release(d3d);
12929 DestroyWindow(window);
12932 static void intz_test(void)
12934 static const DWORD ps_code[] =
12936 0xffff0200, /* ps_2_0 */
12937 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12938 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12939 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
12940 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
12941 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12942 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
12943 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
12944 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
12945 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
12946 0x0000ffff, /* end */
12948 struct
12950 float x, y, z;
12951 float s, t, p, q;
12953 quad[] =
12955 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
12956 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
12957 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
12958 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
12960 half_quad_1[] =
12962 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
12963 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
12964 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
12965 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
12967 half_quad_2[] =
12969 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
12970 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
12971 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
12972 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
12974 struct
12976 UINT x, y;
12977 D3DCOLOR color;
12979 expected_colors[] =
12981 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
12982 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
12983 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
12984 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
12985 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
12986 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
12987 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
12988 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
12991 IDirect3DSurface9 *original_rt, *rt;
12992 IDirect3DTexture9 *texture;
12993 IDirect3DPixelShader9 *ps;
12994 IDirect3DDevice9 *device;
12995 IDirect3DSurface9 *ds;
12996 IDirect3D9 *d3d;
12997 ULONG refcount;
12998 D3DCAPS9 caps;
12999 HWND window;
13000 HRESULT hr;
13001 UINT i;
13003 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13004 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13005 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13006 ok(!!d3d, "Failed to create a D3D object.\n");
13007 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13008 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
13010 skip("No INTZ support, skipping INTZ test.\n");
13011 goto done;
13013 if (!(device = create_device(d3d, window, window, TRUE)))
13015 skip("Failed to create a D3D device, skipping tests.\n");
13016 goto done;
13019 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13020 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13021 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13023 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
13024 IDirect3DDevice9_Release(device);
13025 goto done;
13027 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
13029 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
13030 IDirect3DDevice9_Release(device);
13031 goto done;
13034 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13035 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13037 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13038 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13039 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13040 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13041 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13042 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13043 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13044 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13046 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13047 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13049 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13051 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13053 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13057 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13058 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13059 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13060 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13061 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13062 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13063 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13064 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13065 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13066 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13068 /* Render offscreen, using the INTZ texture as depth buffer */
13069 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13070 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13071 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13072 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13073 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13074 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13075 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13076 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13078 /* Setup the depth/stencil surface. */
13079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13080 ok(SUCCEEDED(hr), "Clear 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, quad, sizeof(*quad));
13085 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13086 hr = IDirect3DDevice9_EndScene(device);
13087 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13089 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13090 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13091 IDirect3DSurface9_Release(ds);
13092 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13093 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13094 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13095 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13096 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13097 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13099 /* Read the depth values back. */
13100 hr = IDirect3DDevice9_BeginScene(device);
13101 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13104 hr = IDirect3DDevice9_EndScene(device);
13105 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13107 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13109 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13110 ok(color_match(color, expected_colors[i].color, 1),
13111 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13112 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13115 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13116 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13118 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13119 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13120 IDirect3DTexture9_Release(texture);
13122 /* Render onscreen while using the INTZ texture as depth buffer */
13123 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13124 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13125 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13126 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13127 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13128 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13130 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13132 /* Setup the depth/stencil surface. */
13133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13134 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13136 hr = IDirect3DDevice9_BeginScene(device);
13137 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13138 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13139 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13140 hr = IDirect3DDevice9_EndScene(device);
13141 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13143 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13144 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13145 IDirect3DSurface9_Release(ds);
13146 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13147 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13148 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13149 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13151 /* Read the depth values back. */
13152 hr = IDirect3DDevice9_BeginScene(device);
13153 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13155 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13156 hr = IDirect3DDevice9_EndScene(device);
13157 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13159 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13161 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13162 ok(color_match(color, expected_colors[i].color, 1),
13163 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13164 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13168 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13170 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13171 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13172 IDirect3DTexture9_Release(texture);
13174 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
13175 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
13176 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
13177 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13178 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13180 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13181 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13182 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13183 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13184 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13185 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13187 /* Setup the depth/stencil surface. */
13188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13189 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13191 hr = IDirect3DDevice9_BeginScene(device);
13192 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
13194 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13195 hr = IDirect3DDevice9_EndScene(device);
13196 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13198 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13199 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13201 hr = IDirect3DDevice9_BeginScene(device);
13202 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
13204 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13205 hr = IDirect3DDevice9_EndScene(device);
13206 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13208 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13209 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13210 IDirect3DSurface9_Release(ds);
13211 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13212 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13213 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13214 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13216 /* Read the depth values back. */
13217 hr = IDirect3DDevice9_BeginScene(device);
13218 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13220 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13221 hr = IDirect3DDevice9_EndScene(device);
13222 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13224 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
13226 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
13227 ok(color_match(color, expected_colors[i].color, 1),
13228 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
13229 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
13232 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13233 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13235 IDirect3DTexture9_Release(texture);
13236 IDirect3DPixelShader9_Release(ps);
13237 IDirect3DSurface9_Release(original_rt);
13238 IDirect3DSurface9_Release(rt);
13239 refcount = IDirect3DDevice9_Release(device);
13240 ok(!refcount, "Device has %u references left.\n", refcount);
13241 done:
13242 IDirect3D9_Release(d3d);
13243 DestroyWindow(window);
13246 static void shadow_test(void)
13248 static const DWORD ps_code[] =
13250 0xffff0200, /* ps_2_0 */
13251 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
13252 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
13253 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
13254 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
13255 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
13256 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
13257 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
13258 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
13259 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
13260 0x0000ffff, /* end */
13262 struct
13264 D3DFORMAT format;
13265 const char *name;
13267 formats[] =
13269 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
13270 {D3DFMT_D32, "D3DFMT_D32"},
13271 {D3DFMT_D15S1, "D3DFMT_D15S1"},
13272 {D3DFMT_D24S8, "D3DFMT_D24S8"},
13273 {D3DFMT_D24X8, "D3DFMT_D24X8"},
13274 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
13275 {D3DFMT_D16, "D3DFMT_D16"},
13276 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
13277 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
13279 struct
13281 float x, y, z;
13282 float s, t, p, q;
13284 quad[] =
13286 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
13287 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
13288 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
13289 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
13291 struct
13293 UINT x, y;
13294 D3DCOLOR color;
13296 expected_colors[] =
13298 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13299 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13300 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
13301 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13302 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
13303 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13304 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13305 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
13308 IDirect3DSurface9 *original_ds, *original_rt, *rt;
13309 IDirect3DPixelShader9 *ps;
13310 IDirect3DDevice9 *device;
13311 IDirect3D9 *d3d;
13312 ULONG refcount;
13313 D3DCAPS9 caps;
13314 HWND window;
13315 HRESULT hr;
13316 UINT i;
13318 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13319 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13320 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13321 ok(!!d3d, "Failed to create a D3D object.\n");
13322 if (!(device = create_device(d3d, window, window, TRUE)))
13324 skip("Failed to create a D3D device, skipping tests.\n");
13325 goto done;
13328 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13329 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13330 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
13332 skip("No pixel shader 2.0 support, skipping shadow test.\n");
13333 IDirect3DDevice9_Release(device);
13334 goto done;
13337 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13338 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13339 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
13340 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13342 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
13343 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13344 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13345 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13346 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13348 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
13349 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13351 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13353 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13355 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13357 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
13360 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
13362 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13363 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
13364 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13365 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
13366 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13367 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
13368 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
13370 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
13372 D3DFORMAT format = formats[i].format;
13373 IDirect3DTexture9 *texture;
13374 IDirect3DSurface9 *ds;
13375 unsigned int j;
13377 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13378 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
13379 continue;
13381 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
13382 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
13383 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13385 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
13386 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13388 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
13389 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13391 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13392 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13394 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13395 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13397 /* Setup the depth/stencil surface. */
13398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13399 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
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 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
13409 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13410 IDirect3DSurface9_Release(ds);
13412 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13413 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13415 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13416 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13418 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13419 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13421 /* Do the actual shadow mapping. */
13422 hr = IDirect3DDevice9_BeginScene(device);
13423 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13425 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13426 hr = IDirect3DDevice9_EndScene(device);
13427 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13429 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13430 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13431 IDirect3DTexture9_Release(texture);
13433 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
13435 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
13436 ok(color_match(color, expected_colors[j].color, 0),
13437 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
13438 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
13439 formats[i].name, color);
13442 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13443 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13446 IDirect3DPixelShader9_Release(ps);
13447 IDirect3DSurface9_Release(original_ds);
13448 IDirect3DSurface9_Release(original_rt);
13449 IDirect3DSurface9_Release(rt);
13450 refcount = IDirect3DDevice9_Release(device);
13451 ok(!refcount, "Device has %u references left.\n", refcount);
13452 done:
13453 IDirect3D9_Release(d3d);
13454 DestroyWindow(window);
13457 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
13459 static const struct vertex quad1[] =
13461 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
13462 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
13463 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
13464 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
13466 static const struct vertex quad2[] =
13468 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
13469 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
13470 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
13471 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
13473 D3DCOLOR color;
13474 HRESULT hr;
13476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
13477 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13479 hr = IDirect3DDevice9_BeginScene(device);
13480 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13482 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13483 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
13486 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13488 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
13491 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13492 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13493 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13495 hr = IDirect3DDevice9_EndScene(device);
13496 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13498 color = getPixelColor(device, 1, 240);
13499 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
13500 color = getPixelColor(device, 638, 240);
13501 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
13503 color = getPixelColor(device, 1, 241);
13504 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
13505 color = getPixelColor(device, 638, 241);
13506 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
13509 static void clip_planes_test(void)
13511 IDirect3DSurface9 *offscreen_surface, *original_rt;
13512 IDirect3DTexture9 *offscreen = NULL;
13513 IDirect3DVertexShader9 *shader;
13514 IDirect3DDevice9 *device;
13515 IDirect3D9 *d3d;
13516 ULONG refcount;
13517 D3DCAPS9 caps;
13518 HWND window;
13519 HRESULT hr;
13521 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
13522 static const DWORD shader_code[] =
13524 0xfffe0200, /* vs_2_0 */
13525 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13526 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
13527 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13528 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
13529 0x0000ffff /* end */
13532 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13533 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13534 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13535 ok(!!d3d, "Failed to create a D3D object.\n");
13536 if (!(device = create_device(d3d, window, window, TRUE)))
13538 skip("Failed to create a D3D device, skipping tests.\n");
13539 goto done;
13542 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13543 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13544 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13546 skip("No vs_2_0 support, skipping tests.\n");
13547 IDirect3DDevice9_Release(device);
13548 goto done;
13551 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
13552 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13555 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
13557 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13559 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13561 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13563 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13564 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
13565 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13566 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
13568 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
13570 clip_planes(device, "Onscreen FFP");
13572 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
13573 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13574 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
13575 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13576 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
13577 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13579 clip_planes(device, "Offscreen FFP");
13581 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13582 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13584 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13585 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
13586 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13587 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
13589 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
13590 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13592 clip_planes(device, "Onscreen vertex shader");
13594 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
13595 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
13597 clip_planes(device, "Offscreen vertex shader");
13599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13600 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13602 IDirect3DVertexShader9_Release(shader);
13603 IDirect3DSurface9_Release(original_rt);
13604 IDirect3DSurface9_Release(offscreen_surface);
13605 IDirect3DTexture9_Release(offscreen);
13606 refcount = IDirect3DDevice9_Release(device);
13607 ok(!refcount, "Device has %u references left.\n", refcount);
13608 done:
13609 IDirect3D9_Release(d3d);
13610 DestroyWindow(window);
13613 static void fp_special_test(void)
13615 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
13616 static const DWORD vs_header[] =
13618 0xfffe0200, /* vs_2_0 */
13619 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
13620 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
13621 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13622 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
13625 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
13626 static const DWORD vs_pow[] =
13627 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
13628 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
13629 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
13630 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
13631 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
13632 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
13633 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
13634 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
13635 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
13636 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
13637 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
13639 static const DWORD vs_footer[] =
13641 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
13642 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
13643 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
13644 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
13645 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
13646 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
13647 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
13648 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
13649 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
13650 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
13651 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
13652 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
13653 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
13654 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
13655 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13656 0x0000ffff, /* end */
13659 static const struct
13661 const char *name;
13662 const DWORD *ops;
13663 DWORD size;
13664 D3DCOLOR r500;
13665 D3DCOLOR r600;
13666 D3DCOLOR nv40;
13667 D3DCOLOR nv50;
13668 D3DCOLOR warp;
13670 vs_body[] =
13672 /* The basic ideas here are:
13673 * 2.0 * +/-INF == +/-INF
13674 * NAN != NAN
13676 * The vertex shader value is written to the red component, with 0.0
13677 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
13678 * result in 0x00. The pixel shader value is written to the green
13679 * component, but here 0.0 also results in 0x00. The actual value is
13680 * written to the blue component.
13682 * There are considerable differences between graphics cards in how
13683 * these are handled, but pow and nrm never generate INF or NAN on
13684 * real hardware. */
13685 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13686 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
13687 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
13688 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13689 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13690 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13691 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13692 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13693 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
13694 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
13695 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
13698 static const DWORD ps_code[] =
13700 0xffff0200, /* ps_2_0 */
13701 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
13702 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
13703 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
13704 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
13705 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
13706 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
13707 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
13708 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
13709 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
13710 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
13711 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
13712 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
13713 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
13714 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
13715 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
13716 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
13717 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
13718 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
13719 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
13720 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
13721 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
13722 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
13723 0x0000ffff, /* end */
13726 struct
13728 float x, y, z;
13729 float s;
13731 quad[] =
13733 { -1.0f, 1.0f, 0.0f, 0.0f},
13734 { 1.0f, 1.0f, 1.0f, 0.0f},
13735 { -1.0f, -1.0f, 0.0f, 0.0f},
13736 { 1.0f, -1.0f, 1.0f, 0.0f},
13739 IDirect3DPixelShader9 *ps;
13740 IDirect3DDevice9 *device;
13741 UINT body_size = 0;
13742 IDirect3D9 *d3d;
13743 DWORD *vs_code;
13744 ULONG refcount;
13745 D3DCAPS9 caps;
13746 HWND window;
13747 HRESULT hr;
13748 UINT i;
13750 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13751 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13752 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13753 ok(!!d3d, "Failed to create a D3D object.\n");
13754 if (!(device = create_device(d3d, window, window, TRUE)))
13756 skip("Failed to create a D3D device, skipping tests.\n");
13757 goto done;
13760 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13761 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
13762 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13764 skip("No shader model 2.0 support, skipping floating point specials test.\n");
13765 IDirect3DDevice9_Release(device);
13766 goto done;
13769 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
13770 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13772 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
13773 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
13774 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13775 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13778 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13780 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
13781 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13783 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
13785 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
13788 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
13789 memcpy(vs_code, vs_header, sizeof(vs_header));
13791 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
13793 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
13794 IDirect3DVertexShader9 *vs;
13795 D3DCOLOR color;
13797 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
13798 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
13799 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
13801 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
13802 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
13803 hr = IDirect3DDevice9_SetVertexShader(device, vs);
13804 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
13806 hr = IDirect3DDevice9_BeginScene(device);
13807 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13809 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13810 hr = IDirect3DDevice9_EndScene(device);
13811 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13813 color = getPixelColor(device, 320, 240);
13814 ok(color_match(color, vs_body[i].r500, 1)
13815 || color_match(color, vs_body[i].r600, 1)
13816 || color_match(color, vs_body[i].nv40, 1)
13817 || color_match(color, vs_body[i].nv50, 1)
13818 || broken(color_match(color, vs_body[i].warp, 1)),
13819 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
13820 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
13822 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13823 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13825 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
13826 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
13827 IDirect3DVertexShader9_Release(vs);
13830 HeapFree(GetProcessHeap(), 0, vs_code);
13832 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
13833 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
13834 IDirect3DPixelShader9_Release(ps);
13835 refcount = IDirect3DDevice9_Release(device);
13836 ok(!refcount, "Device has %u references left.\n", refcount);
13837 done:
13838 IDirect3D9_Release(d3d);
13839 DestroyWindow(window);
13842 static void srgbwrite_format_test(void)
13844 IDirect3D9 *d3d;
13845 IDirect3DSurface9 *rt, *backbuffer;
13846 IDirect3DTexture9 *texture;
13847 IDirect3DDevice9 *device;
13848 ULONG refcount;
13849 HWND window;
13850 HRESULT hr;
13851 int i;
13852 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
13853 static const struct
13855 D3DFORMAT fmt;
13856 const char *name;
13858 formats[] =
13860 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
13861 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
13862 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
13863 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
13864 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
13866 static const struct
13868 float x, y, z;
13869 float u, v;
13871 quad[] =
13873 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
13874 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
13875 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
13876 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
13879 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13880 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13881 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13882 ok(!!d3d, "Failed to create a D3D object.\n");
13883 if (!(device = create_device(d3d, window, window, TRUE)))
13885 skip("Failed to create a D3D device, skipping tests.\n");
13886 goto done;
13889 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
13890 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13891 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
13892 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
13893 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13894 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
13896 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13898 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
13900 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13901 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
13903 skip("Format %s not supported as render target, skipping test.\n",
13904 formats[i].name);
13905 continue;
13908 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
13909 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
13910 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
13911 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13912 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13914 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
13915 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
13916 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
13917 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
13919 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13921 hr = IDirect3DDevice9_BeginScene(device);
13922 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13923 if(SUCCEEDED(hr))
13925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
13926 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13927 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
13928 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13930 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
13932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
13933 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13935 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13936 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
13937 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13938 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13939 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
13940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13941 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
13942 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13943 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
13945 hr = IDirect3DDevice9_EndScene(device);
13946 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13949 IDirect3DSurface9_Release(rt);
13950 IDirect3DTexture9_Release(texture);
13952 color = getPixelColor(device, 360, 240);
13953 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
13954 D3DUSAGE_QUERY_SRGBWRITE,
13955 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
13957 /* Big slop for R5G6B5 */
13958 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
13959 formats[i].name, color_srgb, color);
13961 else
13963 /* Big slop for R5G6B5 */
13964 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
13965 formats[i].name, color_rgb, color);
13968 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13969 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
13972 IDirect3DSurface9_Release(backbuffer);
13973 refcount = IDirect3DDevice9_Release(device);
13974 ok(!refcount, "Device has %u references left.\n", refcount);
13975 done:
13976 IDirect3D9_Release(d3d);
13977 DestroyWindow(window);
13980 static void ds_size_test(IDirect3DDevice9 *device)
13982 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
13983 HRESULT hr;
13984 DWORD num_passes;
13985 struct
13987 float x, y, z;
13989 quad[] =
13991 {-1.0, -1.0, 0.0 },
13992 {-1.0, 1.0, 0.0 },
13993 { 1.0, -1.0, 0.0 },
13994 { 1.0, 1.0, 0.0 }
13997 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
13998 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
13999 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
14000 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
14001 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
14002 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
14004 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14005 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14006 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
14007 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14009 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14010 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14011 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14012 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14013 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14014 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
14015 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
14016 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14017 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14018 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14020 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14021 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14023 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
14024 * but does not change the surface's contents. */
14025 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
14026 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
14027 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
14028 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
14029 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
14030 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
14032 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
14034 /* Turning on any depth-related state results in a ValidateDevice failure */
14035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14036 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14037 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14038 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14039 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14043 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
14044 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14045 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
14046 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
14048 /* Try to draw with the device in an invalid state */
14049 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14050 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
14051 hr = IDirect3DDevice9_BeginScene(device);
14052 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14053 if(SUCCEEDED(hr))
14055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14056 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14057 hr = IDirect3DDevice9_EndScene(device);
14058 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14060 /* Don't check the resulting draw unless we find an app that needs it. On nvidia ValidateDevice
14061 * returns CONFLICTINGRENDERSTATE, so the result is undefined. On AMD d3d seems to assume the
14062 * stored Z buffer value is 0.0 for all pixels, even those that are covered by the depth buffer */
14065 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
14066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14067 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
14068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
14069 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
14070 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
14072 IDirect3DSurface9_Release(readback);
14073 IDirect3DSurface9_Release(ds);
14074 IDirect3DSurface9_Release(rt);
14075 IDirect3DSurface9_Release(old_rt);
14076 IDirect3DSurface9_Release(old_ds);
14079 static void unbound_sampler_test(void)
14081 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
14082 IDirect3DSurface9 *rt, *old_rt;
14083 IDirect3DDevice9 *device;
14084 IDirect3D9 *d3d;
14085 ULONG refcount;
14086 D3DCAPS9 caps;
14087 DWORD color;
14088 HWND window;
14089 HRESULT hr;
14091 static const DWORD ps_code[] =
14093 0xffff0200, /* ps_2_0 */
14094 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14095 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14096 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14097 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14098 0x0000ffff, /* end */
14100 static const DWORD ps_code_cube[] =
14102 0xffff0200, /* ps_2_0 */
14103 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
14104 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14105 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14106 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14107 0x0000ffff, /* end */
14109 static const DWORD ps_code_volume[] =
14111 0xffff0200, /* ps_2_0 */
14112 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
14113 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14114 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14115 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14116 0x0000ffff, /* end */
14119 static const struct
14121 float x, y, z;
14122 float u, v;
14124 quad[] =
14126 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
14127 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
14128 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
14129 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
14132 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14133 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14134 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14135 ok(!!d3d, "Failed to create a D3D object.\n");
14136 if (!(device = create_device(d3d, window, window, TRUE)))
14138 skip("Failed to create a D3D device, skipping tests.\n");
14139 goto done;
14142 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14143 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14144 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14146 skip("No ps_2_0 support, skipping tests.\n");
14147 IDirect3DDevice9_Release(device);
14148 goto done;
14150 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
14152 skip("No cube / volume texture support, skipping tests.\n");
14153 IDirect3DDevice9_Release(device);
14154 goto done;
14157 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14158 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
14160 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14161 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14162 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
14163 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14164 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
14165 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
14167 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
14168 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
14170 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
14171 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
14173 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14174 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
14176 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
14177 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
14179 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
14180 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
14182 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14183 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14185 hr = IDirect3DDevice9_BeginScene(device);
14186 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14187 if(SUCCEEDED(hr))
14189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14190 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14192 hr = IDirect3DDevice9_EndScene(device);
14193 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14196 color = getPixelColorFromSurface(rt, 32, 32);
14197 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14199 /* Now try with a cube texture */
14200 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
14201 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14203 hr = IDirect3DDevice9_BeginScene(device);
14204 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14205 if (SUCCEEDED(hr))
14207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14208 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14210 hr = IDirect3DDevice9_EndScene(device);
14211 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14214 color = getPixelColorFromSurface(rt, 32, 32);
14215 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14217 /* And then with a volume texture */
14218 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
14219 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
14221 hr = IDirect3DDevice9_BeginScene(device);
14222 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
14223 if (SUCCEEDED(hr))
14225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14226 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
14228 hr = IDirect3DDevice9_EndScene(device);
14229 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
14232 color = getPixelColorFromSurface(rt, 32, 32);
14233 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
14235 IDirect3DSurface9_Release(rt);
14236 IDirect3DSurface9_Release(old_rt);
14237 IDirect3DPixelShader9_Release(ps);
14238 IDirect3DPixelShader9_Release(ps_cube);
14239 IDirect3DPixelShader9_Release(ps_volume);
14240 refcount = IDirect3DDevice9_Release(device);
14241 ok(!refcount, "Device has %u references left.\n", refcount);
14242 done:
14243 IDirect3D9_Release(d3d);
14244 DestroyWindow(window);
14247 static void update_surface_test(void)
14249 static const BYTE blocks[][8] =
14251 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
14252 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
14253 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
14254 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
14255 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
14256 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
14257 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
14259 static const struct
14261 UINT x, y;
14262 D3DCOLOR color;
14264 expected_colors[] =
14266 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
14267 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
14268 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
14269 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
14270 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
14271 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
14272 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
14274 static const struct
14276 float x, y, z, w;
14277 float u, v;
14279 tri[] =
14281 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
14282 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
14283 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
14285 static const RECT rect_2x2 = {0, 0, 2, 2};
14286 static const struct
14288 UINT src_level;
14289 UINT dst_level;
14290 const RECT *r;
14291 HRESULT hr;
14293 block_size_tests[] =
14295 {1, 0, NULL, D3D_OK},
14296 {0, 1, NULL, D3DERR_INVALIDCALL},
14297 {5, 4, NULL, D3DERR_INVALIDCALL},
14298 {4, 5, NULL, D3DERR_INVALIDCALL},
14299 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
14300 {5, 5, &rect_2x2, D3D_OK},
14303 IDirect3DSurface9 *src_surface, *dst_surface;
14304 IDirect3DTexture9 *src_tex, *dst_tex;
14305 IDirect3DDevice9 *device;
14306 IDirect3D9 *d3d;
14307 ULONG refcount;
14308 UINT count, i;
14309 HWND window;
14310 HRESULT hr;
14312 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14313 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14314 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14315 ok(!!d3d, "Failed to create a D3D object.\n");
14316 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14317 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
14319 skip("DXT1 not supported, skipping tests.\n");
14320 goto done;
14322 if (!(device = create_device(d3d, window, window, TRUE)))
14324 skip("Failed to create a D3D device, skipping tests.\n");
14325 goto done;
14328 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
14329 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
14330 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
14331 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
14333 count = IDirect3DTexture9_GetLevelCount(src_tex);
14334 ok(count == 7, "Got level count %u, expected 7.\n", count);
14336 for (i = 0; i < count; ++i)
14338 UINT row_count, block_count, x, y;
14339 D3DSURFACE_DESC desc;
14340 BYTE *row, *block;
14341 D3DLOCKED_RECT r;
14343 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
14344 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
14346 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
14347 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
14349 row_count = ((desc.Height + 3) & ~3) / 4;
14350 block_count = ((desc.Width + 3) & ~3) / 4;
14351 row = r.pBits;
14353 for (y = 0; y < row_count; ++y)
14355 block = row;
14356 for (x = 0; x < block_count; ++x)
14358 memcpy(block, blocks[i], sizeof(blocks[i]));
14359 block += sizeof(blocks[i]);
14361 row += r.Pitch;
14364 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
14365 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
14368 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
14370 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
14371 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14372 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
14373 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14375 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
14376 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
14377 hr, i, block_size_tests[i].hr);
14379 IDirect3DSurface9_Release(dst_surface);
14380 IDirect3DSurface9_Release(src_surface);
14383 for (i = 0; i < count; ++i)
14385 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
14386 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14387 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
14388 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
14390 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
14391 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
14393 IDirect3DSurface9_Release(dst_surface);
14394 IDirect3DSurface9_Release(src_surface);
14397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14398 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14399 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14400 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14401 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
14402 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14403 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
14404 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14405 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14406 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14407 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14408 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
14410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
14411 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14413 hr = IDirect3DDevice9_BeginScene(device);
14414 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
14416 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14417 hr = IDirect3DDevice9_EndScene(device);
14418 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14420 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14422 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
14423 ok(color_match(color, expected_colors[i].color, 0),
14424 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14425 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14428 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14429 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14431 IDirect3DTexture9_Release(dst_tex);
14432 IDirect3DTexture9_Release(src_tex);
14433 refcount = IDirect3DDevice9_Release(device);
14434 ok(!refcount, "Device has %u references left.\n", refcount);
14435 done:
14436 IDirect3D9_Release(d3d);
14437 DestroyWindow(window);
14440 static void multisample_get_rtdata_test(void)
14442 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
14443 IDirect3DDevice9 *device;
14444 IDirect3D9 *d3d;
14445 ULONG refcount;
14446 HWND window;
14447 HRESULT hr;
14449 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14450 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14451 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14452 ok(!!d3d, "Failed to create a D3D object.\n");
14453 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14454 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14456 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
14457 goto done;
14459 if (!(device = create_device(d3d, window, window, TRUE)))
14461 skip("Failed to create a D3D device, skipping tests.\n");
14462 goto done;
14465 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
14466 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14467 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14468 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
14469 D3DPOOL_SYSTEMMEM, &readback, NULL);
14470 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14472 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14473 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14474 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14475 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14477 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14478 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14479 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14480 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14482 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
14483 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14484 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
14485 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
14487 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
14488 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14489 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14490 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
14492 IDirect3DSurface9_Release(original_ds);
14493 IDirect3DSurface9_Release(original_rt);
14494 IDirect3DSurface9_Release(readback);
14495 IDirect3DSurface9_Release(rt);
14496 refcount = IDirect3DDevice9_Release(device);
14497 ok(!refcount, "Device has %u references left.\n", refcount);
14498 done:
14499 IDirect3D9_Release(d3d);
14500 DestroyWindow(window);
14503 static void multisampled_depth_buffer_test(void)
14505 IDirect3DDevice9 *device = 0;
14506 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
14507 IDirect3D9 *d3d;
14508 D3DCAPS9 caps;
14509 HRESULT hr;
14510 D3DPRESENT_PARAMETERS present_parameters;
14511 unsigned int i;
14512 static const struct
14514 float x, y, z;
14515 D3DCOLOR color;
14517 quad_1[] =
14519 { -1.0f, 1.0f, 0.0f, 0xffff0000},
14520 { 1.0f, 1.0f, 1.0f, 0xffff0000},
14521 { -1.0f, -1.0f, 0.0f, 0xffff0000},
14522 { 1.0f, -1.0f, 1.0f, 0xffff0000},
14524 quad_2[] =
14526 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
14527 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
14528 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
14529 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
14531 static const struct
14533 UINT x, y;
14534 D3DCOLOR color;
14536 expected_colors[] =
14538 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14539 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14540 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14541 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14542 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14543 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
14544 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14545 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
14548 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14549 ok(!!d3d, "Failed to create a D3D object.\n");
14551 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14552 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14554 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
14555 IDirect3D9_Release(d3d);
14556 return;
14558 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14559 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14561 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
14562 IDirect3D9_Release(d3d);
14563 return;
14566 ZeroMemory(&present_parameters, sizeof(present_parameters));
14567 present_parameters.Windowed = TRUE;
14568 present_parameters.hDeviceWindow = create_window();
14569 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14570 present_parameters.BackBufferWidth = 640;
14571 present_parameters.BackBufferHeight = 480;
14572 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14573 present_parameters.EnableAutoDepthStencil = TRUE;
14574 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14575 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
14577 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14578 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
14579 &present_parameters, &device);
14580 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14582 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14583 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14584 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14586 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
14587 goto cleanup;
14590 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14591 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14592 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14593 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14594 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14595 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14597 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14598 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14599 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
14600 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14603 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14605 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14607 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14609 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14610 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14611 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14613 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14614 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14616 /* Render onscreen and then offscreen */
14617 hr = IDirect3DDevice9_BeginScene(device);
14618 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14619 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14620 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14621 hr = IDirect3DDevice9_EndScene(device);
14622 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14624 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
14625 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14626 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14627 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14629 hr = IDirect3DDevice9_BeginScene(device);
14630 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14632 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14633 hr = IDirect3DDevice9_EndScene(device);
14634 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14636 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
14637 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14639 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14641 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14642 ok(color_match(color, expected_colors[i].color, 1),
14643 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14644 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14647 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14648 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14649 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14650 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14652 /* Render offscreen and then onscreen */
14653 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14654 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14655 IDirect3DSurface9_Release(ds);
14656 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14657 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
14658 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14659 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14661 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14662 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14664 hr = IDirect3DDevice9_BeginScene(device);
14665 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14666 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14667 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14668 hr = IDirect3DDevice9_EndScene(device);
14669 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14671 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14672 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14673 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14674 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14676 hr = IDirect3DDevice9_BeginScene(device);
14677 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14679 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14680 hr = IDirect3DDevice9_EndScene(device);
14681 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14683 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
14684 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14686 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14688 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14689 ok(color_match(color, expected_colors[i].color, 1),
14690 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14691 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14695 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14697 IDirect3DSurface9_Release(ds);
14698 IDirect3DSurface9_Release(readback);
14699 IDirect3DSurface9_Release(rt);
14700 IDirect3DSurface9_Release(original_rt);
14701 cleanup_device(device);
14703 ZeroMemory(&present_parameters, sizeof(present_parameters));
14704 present_parameters.Windowed = TRUE;
14705 present_parameters.hDeviceWindow = create_window();
14706 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14707 present_parameters.BackBufferWidth = 640;
14708 present_parameters.BackBufferHeight = 480;
14709 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14710 present_parameters.EnableAutoDepthStencil = TRUE;
14711 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14712 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
14714 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14715 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
14716 &present_parameters, &device);
14717 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14719 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
14720 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
14722 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14723 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14724 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14725 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14726 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14727 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14728 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14729 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
14730 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14732 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14733 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14734 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14735 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
14736 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14737 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14738 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14739 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14742 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14744 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14746 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14748 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14749 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14750 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14752 /* Render to a multisampled offscreen frame buffer and then blit to
14753 * the onscreen (not multisampled) frame buffer. */
14754 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14755 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14757 hr = IDirect3DDevice9_BeginScene(device);
14758 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
14760 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14761 hr = IDirect3DDevice9_EndScene(device);
14762 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14764 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
14765 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14766 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
14767 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14769 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14770 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14771 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
14772 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14774 hr = IDirect3DDevice9_BeginScene(device);
14775 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
14777 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14778 hr = IDirect3DDevice9_EndScene(device);
14779 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14781 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
14782 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14784 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14786 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
14787 ok(color_match(color, expected_colors[i].color, 1),
14788 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14789 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14793 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14795 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14796 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14797 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14798 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
14800 IDirect3DSurface9_Release(original_ds);
14801 IDirect3DSurface9_Release(original_rt);
14802 IDirect3DSurface9_Release(ds);
14803 IDirect3DSurface9_Release(readback);
14804 IDirect3DSurface9_Release(rt);
14805 cleanup:
14806 cleanup_device(device);
14807 IDirect3D9_Release(d3d);
14810 static void resz_test(void)
14812 IDirect3DDevice9 *device = 0;
14813 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
14814 D3DCAPS9 caps;
14815 HRESULT hr;
14816 D3DPRESENT_PARAMETERS present_parameters;
14817 unsigned int i;
14818 static const DWORD ps_code[] =
14820 0xffff0200, /* ps_2_0 */
14821 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14822 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14823 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14824 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14825 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14826 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
14827 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
14828 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
14829 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
14830 0x0000ffff, /* end */
14832 struct
14834 float x, y, z;
14835 float s, t, p, q;
14837 quad[] =
14839 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14840 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14841 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14842 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14844 struct
14846 UINT x, y;
14847 D3DCOLOR color;
14849 expected_colors[] =
14851 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
14852 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
14853 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
14854 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
14855 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
14856 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
14857 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
14858 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
14860 IDirect3DTexture9 *texture;
14861 IDirect3DPixelShader9 *ps;
14862 IDirect3D9 *d3d;
14863 DWORD value;
14865 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14866 ok(!!d3d, "Failed to create a D3D object.\n");
14868 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14869 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14871 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
14872 IDirect3D9_Release(d3d);
14873 return;
14875 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
14876 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
14878 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
14879 IDirect3D9_Release(d3d);
14880 return;
14883 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14884 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14886 skip("No INTZ support, skipping RESZ test.\n");
14887 IDirect3D9_Release(d3d);
14888 return;
14891 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
14892 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
14894 skip("No RESZ support, skipping RESZ test.\n");
14895 IDirect3D9_Release(d3d);
14896 return;
14899 ZeroMemory(&present_parameters, sizeof(present_parameters));
14900 present_parameters.Windowed = TRUE;
14901 present_parameters.hDeviceWindow = create_window();
14902 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
14903 present_parameters.BackBufferWidth = 640;
14904 present_parameters.BackBufferHeight = 480;
14905 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
14906 present_parameters.EnableAutoDepthStencil = FALSE;
14907 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
14908 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
14910 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14911 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
14912 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
14914 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14915 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14916 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14918 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14919 cleanup_device(device);
14920 IDirect3D9_Release(d3d);
14921 return;
14923 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14925 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14926 cleanup_device(device);
14927 IDirect3D9_Release(d3d);
14928 return;
14931 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14932 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
14934 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14935 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
14936 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
14937 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
14938 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
14939 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14940 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
14941 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
14943 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14944 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14945 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14946 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
14947 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14948 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
14949 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14951 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
14952 IDirect3DSurface9_Release(intz_ds);
14953 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14954 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14956 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14957 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14959 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14961 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14963 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14967 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14968 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14969 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14970 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14971 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14972 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14973 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14974 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14975 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14976 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14978 /* Render offscreen (multisampled), blit the depth buffer
14979 * into the INTZ texture and then check its contents */
14980 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14981 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
14982 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14983 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
14984 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
14985 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
14987 hr = IDirect3DDevice9_BeginScene(device);
14988 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14990 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14992 /* The destination depth texture has to be bound to sampler 0 */
14993 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14994 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14996 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
14997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14998 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15000 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15002 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15004 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15006 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15008 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15010 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15012 /* The actual multisampled depth buffer resolve happens here */
15013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15014 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15015 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15016 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15018 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15019 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15020 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15021 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15023 /* Read the depth values back */
15024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15025 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15026 hr = IDirect3DDevice9_EndScene(device);
15027 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15029 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15031 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15032 ok(color_match(color, expected_colors[i].color, 1),
15033 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15034 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15037 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15038 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15040 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15041 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15042 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15043 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15044 IDirect3DSurface9_Release(ds);
15045 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15046 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15047 IDirect3DTexture9_Release(texture);
15048 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15049 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15050 IDirect3DPixelShader9_Release(ps);
15051 IDirect3DSurface9_Release(readback);
15052 IDirect3DSurface9_Release(original_rt);
15053 IDirect3DSurface9_Release(rt);
15054 cleanup_device(device);
15057 ZeroMemory(&present_parameters, sizeof(present_parameters));
15058 present_parameters.Windowed = TRUE;
15059 present_parameters.hDeviceWindow = create_window();
15060 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15061 present_parameters.BackBufferWidth = 640;
15062 present_parameters.BackBufferHeight = 480;
15063 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15064 present_parameters.EnableAutoDepthStencil = TRUE;
15065 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15066 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15068 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15069 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
15070 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15072 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15073 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15074 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15075 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15076 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15077 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15078 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15079 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15080 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15081 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15082 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
15083 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15084 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15085 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15086 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
15087 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15088 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15089 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
15090 IDirect3DSurface9_Release(intz_ds);
15091 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15092 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15094 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15095 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15097 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15099 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15101 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15103 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15105 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15106 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15107 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15108 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15109 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15110 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15111 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15112 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15113 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15114 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15116 /* Render onscreen, blit the depth buffer into the INTZ texture
15117 * and then check its contents */
15118 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15119 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15120 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15121 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15122 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15123 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15125 hr = IDirect3DDevice9_BeginScene(device);
15126 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15128 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15129 hr = IDirect3DDevice9_EndScene(device);
15130 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15132 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15133 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15136 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15138 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15140 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15141 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15142 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15144 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15146 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15148 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15150 /* The actual multisampled depth buffer resolve happens here */
15151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15152 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15153 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
15154 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
15156 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15157 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15158 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15159 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15161 /* Read the depth values back */
15162 hr = IDirect3DDevice9_BeginScene(device);
15163 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15164 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15165 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15166 hr = IDirect3DDevice9_EndScene(device);
15167 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15169 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15171 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15172 ok(color_match(color, expected_colors[i].color, 1),
15173 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15174 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15178 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15181 /* Test edge cases - try with no texture at all */
15182 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15183 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15184 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15185 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15187 hr = IDirect3DDevice9_BeginScene(device);
15188 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15190 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15191 hr = IDirect3DDevice9_EndScene(device);
15192 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15195 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15197 /* With a non-multisampled depth buffer */
15198 IDirect3DSurface9_Release(ds);
15199 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15200 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15202 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
15203 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15204 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15205 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15206 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15207 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15209 hr = IDirect3DDevice9_BeginScene(device);
15210 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15212 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15214 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15215 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15218 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15220 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
15222 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15223 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15224 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15226 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15228 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
15230 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15231 hr = IDirect3DDevice9_EndScene(device);
15232 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15235 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15237 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15238 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15240 /* Read the depth values back. */
15241 hr = IDirect3DDevice9_BeginScene(device);
15242 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15244 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15245 hr = IDirect3DDevice9_EndScene(device);
15246 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15248 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15250 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15251 ok(color_match(color, expected_colors[i].color, 1),
15252 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15253 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15257 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15259 /* Without a current depth-stencil buffer set */
15260 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15261 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15262 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15263 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15265 hr = IDirect3DDevice9_BeginScene(device);
15266 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15268 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15269 hr = IDirect3DDevice9_EndScene(device);
15270 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
15273 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
15275 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15276 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15277 IDirect3DSurface9_Release(ds);
15278 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15279 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15280 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15281 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15282 IDirect3DTexture9_Release(texture);
15283 IDirect3DPixelShader9_Release(ps);
15284 IDirect3DSurface9_Release(readback);
15285 IDirect3DSurface9_Release(original_rt);
15286 cleanup_device(device);
15287 IDirect3D9_Release(d3d);
15290 static void zenable_test(void)
15292 static const struct
15294 struct vec4 position;
15295 D3DCOLOR diffuse;
15297 tquad[] =
15299 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
15300 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
15301 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
15302 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
15304 IDirect3DDevice9 *device;
15305 IDirect3D9 *d3d;
15306 D3DCOLOR color;
15307 ULONG refcount;
15308 D3DCAPS9 caps;
15309 HWND window;
15310 HRESULT hr;
15311 UINT x, y;
15312 UINT i, j;
15314 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15315 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15316 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15317 ok(!!d3d, "Failed to create a D3D object.\n");
15318 if (!(device = create_device(d3d, window, window, TRUE)))
15320 skip("Failed to create a D3D device, skipping tests.\n");
15321 goto done;
15324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15325 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
15326 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
15327 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
15330 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15331 hr = IDirect3DDevice9_BeginScene(device);
15332 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15333 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
15334 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15335 hr = IDirect3DDevice9_EndScene(device);
15336 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15338 for (i = 0; i < 4; ++i)
15340 for (j = 0; j < 4; ++j)
15342 x = 80 * ((2 * j) + 1);
15343 y = 60 * ((2 * i) + 1);
15344 color = getPixelColor(device, x, y);
15345 ok(color_match(color, 0x0000ff00, 1),
15346 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
15350 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15351 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15353 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15354 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15356 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
15357 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
15359 static const DWORD vs_code[] =
15361 0xfffe0101, /* vs_1_1 */
15362 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15363 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15364 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
15365 0x0000ffff
15367 static const DWORD ps_code[] =
15369 0xffff0101, /* ps_1_1 */
15370 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
15371 0x0000ffff /* end */
15373 static const struct vec3 quad[] =
15375 {-1.0f, -1.0f, -0.5f},
15376 {-1.0f, 1.0f, -0.5f},
15377 { 1.0f, -1.0f, 1.5f},
15378 { 1.0f, 1.0f, 1.5f},
15380 static const D3DCOLOR expected[] =
15382 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
15383 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
15384 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
15385 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
15387 /* The Windows 8 testbot (WARP) appears to not clip z for regular
15388 * vertices either. */
15389 static const D3DCOLOR expected_broken[] =
15391 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
15392 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
15393 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
15394 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
15397 IDirect3DVertexShader9 *vs;
15398 IDirect3DPixelShader9 *ps;
15400 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15401 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15402 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15403 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
15404 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15405 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15406 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15407 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15408 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15409 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15411 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
15412 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15413 hr = IDirect3DDevice9_BeginScene(device);
15414 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15416 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15417 hr = IDirect3DDevice9_EndScene(device);
15418 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15420 for (i = 0; i < 4; ++i)
15422 for (j = 0; j < 4; ++j)
15424 x = 80 * ((2 * j) + 1);
15425 y = 60 * ((2 * i) + 1);
15426 color = getPixelColor(device, x, y);
15427 ok(color_match(color, expected[i * 4 + j], 1)
15428 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
15429 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
15433 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15434 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15436 IDirect3DPixelShader9_Release(ps);
15437 IDirect3DVertexShader9_Release(vs);
15440 refcount = IDirect3DDevice9_Release(device);
15441 ok(!refcount, "Device has %u references left.\n", refcount);
15442 done:
15443 IDirect3D9_Release(d3d);
15444 DestroyWindow(window);
15447 static void fog_special_test(void)
15449 static const struct
15451 struct vec3 position;
15452 D3DCOLOR diffuse;
15454 quad[] =
15456 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
15457 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
15458 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
15459 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
15461 static const struct
15463 DWORD vertexmode, tablemode;
15464 BOOL vs, ps;
15465 D3DCOLOR color_left, color_right;
15467 tests[] =
15469 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
15470 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
15471 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
15472 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
15474 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
15475 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
15476 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
15477 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
15479 static const DWORD pixel_shader_code[] =
15481 0xffff0101, /* ps_1_1 */
15482 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
15483 0x0000ffff
15485 static const DWORD vertex_shader_code[] =
15487 0xfffe0101, /* vs_1_1 */
15488 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15489 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
15490 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15491 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
15492 0x0000ffff
15494 static const D3DMATRIX identity =
15496 1.0f, 0.0f, 0.0f, 0.0f,
15497 0.0f, 1.0f, 0.0f, 0.0f,
15498 0.0f, 0.0f, 1.0f, 0.0f,
15499 0.0f, 0.0f, 0.0f, 1.0f,
15500 }}};
15501 union
15503 float f;
15504 DWORD d;
15505 } conv;
15506 DWORD color;
15507 HRESULT hr;
15508 unsigned int i;
15509 IDirect3DPixelShader9 *ps;
15510 IDirect3DVertexShader9 *vs;
15511 IDirect3DDevice9 *device;
15512 IDirect3D9 *d3d;
15513 ULONG refcount;
15514 D3DCAPS9 caps;
15515 HWND window;
15517 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15518 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15519 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15520 ok(!!d3d, "Failed to create a D3D object.\n");
15521 if (!(device = create_device(d3d, window, window, TRUE)))
15523 skip("Failed to create a D3D device, skipping tests.\n");
15524 goto done;
15527 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15528 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15529 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
15531 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
15532 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
15534 else
15536 skip("Vertex Shaders not supported, skipping some fog tests.\n");
15537 vs = NULL;
15539 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
15541 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
15542 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15544 else
15546 skip("Pixel Shaders not supported, skipping some fog tests.\n");
15547 ps = NULL;
15550 /* The table fog tests seem to depend on the projection matrix explicitly
15551 * being set to an identity matrix, even though that's the default.
15552 * (AMD Radeon HD 6310, Windows 7) */
15553 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
15554 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
15556 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15557 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15559 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
15560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
15561 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
15562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
15563 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
15565 conv.f = 0.5f;
15566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
15567 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
15568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
15569 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
15571 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
15573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15574 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15576 if (!tests[i].vs)
15578 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15579 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15581 else if (vs)
15583 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15584 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
15586 else
15588 continue;
15591 if (!tests[i].ps)
15593 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15594 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15596 else if (ps)
15598 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15599 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15601 else
15603 continue;
15606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
15607 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
15608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
15609 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
15611 hr = IDirect3DDevice9_BeginScene(device);
15612 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15614 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15615 hr = IDirect3DDevice9_EndScene(device);
15616 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15618 color = getPixelColor(device, 310, 240);
15619 ok(color_match(color, tests[i].color_left, 1),
15620 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
15621 color = getPixelColor(device, 330, 240);
15622 ok(color_match(color, tests[i].color_right, 1),
15623 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
15625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15626 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15629 if (vs)
15630 IDirect3DVertexShader9_Release(vs);
15631 if (ps)
15632 IDirect3DPixelShader9_Release(ps);
15633 refcount = IDirect3DDevice9_Release(device);
15634 ok(!refcount, "Device has %u references left.\n", refcount);
15635 done:
15636 IDirect3D9_Release(d3d);
15637 DestroyWindow(window);
15640 static void volume_srgb_test(void)
15642 HRESULT hr;
15643 unsigned int i, j;
15644 IDirect3DVolumeTexture9 *tex1, *tex2;
15645 D3DPOOL pool;
15646 D3DLOCKED_BOX locked_box;
15647 IDirect3DDevice9 *device;
15648 IDirect3D9 *d3d;
15649 D3DCOLOR color;
15650 ULONG refcount;
15651 HWND window;
15653 static const struct
15655 BOOL srgb;
15656 DWORD color;
15658 tests[] =
15660 /* Try toggling on and off */
15661 { FALSE, 0x007f7f7f },
15662 { TRUE, 0x00363636 },
15663 { FALSE, 0x007f7f7f },
15665 static const struct
15667 struct vec3 pos;
15668 struct vec3 texcrd;
15670 quad[] =
15672 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15673 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15674 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15675 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
15678 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15679 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15680 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15681 ok(!!d3d, "Failed to create a D3D object.\n");
15682 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15683 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
15685 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
15686 goto done;
15688 if (!(device = create_device(d3d, window, window, TRUE)))
15690 skip("Failed to create a D3D device, skipping tests.\n");
15691 goto done;
15694 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15695 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
15696 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15697 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
15698 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
15699 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
15700 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
15701 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
15703 for (i = 0; i < 2; i++)
15705 if (!i)
15706 pool = D3DPOOL_SYSTEMMEM;
15707 else
15708 pool = D3DPOOL_MANAGED;
15710 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
15711 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15712 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
15713 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15714 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
15715 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
15716 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15718 if (!i)
15720 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
15721 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
15722 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15723 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
15724 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
15725 IDirect3DVolumeTexture9_Release(tex1);
15727 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
15728 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15729 IDirect3DVolumeTexture9_Release(tex2);
15731 else
15733 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
15734 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15735 IDirect3DVolumeTexture9_Release(tex1);
15738 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
15740 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
15741 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
15743 hr = IDirect3DDevice9_BeginScene(device);
15744 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15745 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15746 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15747 hr = IDirect3DDevice9_EndScene(device);
15748 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15750 color = getPixelColor(device, 320, 240);
15751 ok(color_match(color, tests[j].color, 2),
15752 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
15754 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15755 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
15759 refcount = IDirect3DDevice9_Release(device);
15760 ok(!refcount, "Device has %u references left.\n", refcount);
15761 done:
15762 IDirect3D9_Release(d3d);
15763 DestroyWindow(window);
15766 static void volume_dxt5_test(void)
15768 IDirect3DVolumeTexture9 *texture;
15769 IDirect3DDevice9 *device;
15770 D3DLOCKED_BOX box;
15771 IDirect3D9 *d3d;
15772 unsigned int i;
15773 ULONG refcount;
15774 DWORD color;
15775 HWND window;
15776 HRESULT hr;
15778 static const char texture_data[] =
15780 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
15781 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
15782 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
15783 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
15784 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
15786 static const struct
15788 struct vec3 position;
15789 struct vec3 texcrd;
15791 quads[] =
15793 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
15794 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
15795 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
15796 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
15798 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
15799 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
15800 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
15801 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
15803 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
15805 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15806 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15807 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15808 ok(!!d3d, "Failed to create a D3D object.\n");
15809 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15810 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
15812 skip("DXT5 volume textures are not supported, skipping test.\n");
15813 goto done;
15815 if (!(device = create_device(d3d, window, window, TRUE)))
15817 skip("Failed to create a D3D device, skipping tests.\n");
15818 goto done;
15821 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
15822 D3DPOOL_MANAGED, &texture, NULL);
15823 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15825 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
15826 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15827 memcpy(box.pBits, texture_data, sizeof(texture_data));
15828 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
15829 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
15831 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
15832 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15833 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15834 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15835 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15836 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
15837 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15838 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
15839 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
15840 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
15841 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15842 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
15844 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
15845 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
15846 hr = IDirect3DDevice9_BeginScene(device);
15847 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
15849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15850 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
15851 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15852 hr = IDirect3DDevice9_EndScene(device);
15853 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15855 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15856 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
15857 for (i = 0; i < 4; i++)
15859 color = getPixelColor(device, 80 + 160 * i, 240);
15860 ok (color_match(color, expected_colors[i], 1),
15861 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
15864 IDirect3DVolumeTexture9_Release(texture);
15865 refcount = IDirect3DDevice9_Release(device);
15866 ok(!refcount, "Device has %u references left.\n", refcount);
15867 done:
15868 IDirect3D9_Release(d3d);
15869 DestroyWindow(window);
15872 static void volume_v16u16_test(void)
15874 IDirect3DVolumeTexture9 *texture;
15875 IDirect3DPixelShader9 *shader;
15876 IDirect3DDevice9 *device;
15877 D3DLOCKED_BOX box;
15878 IDirect3D9 *d3d;
15879 unsigned int i;
15880 ULONG refcount;
15881 D3DCAPS9 caps;
15882 SHORT *texel;
15883 DWORD color;
15884 HWND window;
15885 HRESULT hr;
15887 static const struct
15889 struct vec3 position;
15890 struct vec3 texcrd;
15892 quads[] =
15894 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
15895 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
15896 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
15897 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
15899 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
15900 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
15901 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
15902 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
15904 static const DWORD shader_code[] =
15906 0xffff0101, /* ps_1_1 */
15907 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
15908 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
15909 0x00000042, 0xb00f0000, /* tex t0 */
15910 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
15911 0x0000ffff /* end */
15914 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15915 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15916 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15917 ok(!!d3d, "Failed to create a D3D object.\n");
15918 if (!(device = create_device(d3d, window, window, TRUE)))
15920 skip("Failed to create a D3D device, skipping tests.\n");
15921 goto done;
15924 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15925 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15926 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
15928 skip("No ps_1_1 support, skipping tests.\n");
15929 IDirect3DDevice9_Release(device);
15930 goto done;
15932 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15933 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
15935 skip("Volume V16U16 textures are not supported, skipping test.\n");
15936 IDirect3DDevice9_Release(device);
15937 goto done;
15940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
15941 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15942 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
15943 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
15944 hr = IDirect3DDevice9_SetPixelShader(device, shader);
15945 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
15946 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15947 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
15949 for (i = 0; i < 2; i++)
15951 D3DPOOL pool;
15953 if (i)
15954 pool = D3DPOOL_SYSTEMMEM;
15955 else
15956 pool = D3DPOOL_MANAGED;
15958 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
15959 pool, &texture, NULL);
15960 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15962 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
15963 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
15965 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
15966 texel[0] = 32767;
15967 texel[1] = 32767;
15968 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
15969 texel[0] = -32768;
15970 texel[1] = 0;
15971 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
15972 texel[0] = -16384;
15973 texel[1] = 16384;
15974 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
15975 texel[0] = 0;
15976 texel[1] = 0;
15978 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
15979 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
15981 if (i)
15983 IDirect3DVolumeTexture9 *texture2;
15985 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
15986 D3DPOOL_DEFAULT, &texture2, NULL);
15987 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
15989 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
15990 (IDirect3DBaseTexture9 *)texture2);
15991 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
15993 IDirect3DVolumeTexture9_Release(texture);
15994 texture = texture2;
15997 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15998 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16000 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
16001 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
16002 hr = IDirect3DDevice9_BeginScene(device);
16003 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
16005 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
16007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16008 hr = IDirect3DDevice9_EndScene(device);
16009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16011 color = getPixelColor(device, 120, 160);
16012 ok (color_match(color, 0x000080ff, 2),
16013 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
16014 color = getPixelColor(device, 120, 400);
16015 ok (color_match(color, 0x00ffffff, 2),
16016 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
16017 color = getPixelColor(device, 360, 160);
16018 ok (color_match(color, 0x007f7fff, 2),
16019 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
16020 color = getPixelColor(device, 360, 400);
16021 ok (color_match(color, 0x0040c0ff, 2),
16022 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
16024 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16025 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16027 IDirect3DVolumeTexture9_Release(texture);
16030 IDirect3DPixelShader9_Release(shader);
16031 refcount = IDirect3DDevice9_Release(device);
16032 ok(!refcount, "Device has %u references left.\n", refcount);
16033 done:
16034 IDirect3D9_Release(d3d);
16035 DestroyWindow(window);
16038 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
16040 HRESULT hr;
16041 static const struct
16043 struct vec3 position;
16044 struct vec2 texcoord;
16046 quad[] =
16048 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
16049 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
16050 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
16051 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
16054 hr = IDirect3DDevice9_BeginScene(device);
16055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
16057 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16058 hr = IDirect3DDevice9_EndScene(device);
16059 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16062 static void add_dirty_rect_test(void)
16064 HRESULT hr;
16065 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
16066 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
16067 IDirect3DDevice9 *device;
16068 IDirect3D9 *d3d;
16069 unsigned int i;
16070 ULONG refcount;
16071 DWORD *texel;
16072 HWND window;
16073 D3DLOCKED_RECT locked_rect;
16074 static const RECT part_rect = {96, 96, 160, 160};
16075 DWORD color;
16077 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16078 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16079 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16080 ok(!!d3d, "Failed to create a D3D object.\n");
16081 if (!(device = create_device(d3d, window, window, TRUE)))
16083 skip("Failed to create a D3D device, skipping tests.\n");
16084 IDirect3D9_Release(d3d);
16085 DestroyWindow(window);
16086 return;
16089 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16090 D3DPOOL_DEFAULT, &tex_dst1, NULL);
16091 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16092 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16093 D3DPOOL_DEFAULT, &tex_dst2, NULL);
16094 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16095 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16096 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
16097 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16098 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16099 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
16100 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16101 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
16102 D3DPOOL_MANAGED, &tex_managed, NULL);
16103 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
16105 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
16106 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16107 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
16108 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16109 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
16110 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16111 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
16112 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
16114 fill_surface(surface_src_red, 0x00ff0000, 0);
16115 fill_surface(surface_src_green, 0x0000ff00, 0);
16117 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
16118 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16119 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16120 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16121 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16122 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16124 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16125 (IDirect3DBaseTexture9 *)tex_dst1);
16126 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16128 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
16129 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
16130 (IDirect3DBaseTexture9 *)tex_dst2);
16131 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16132 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16133 (IDirect3DBaseTexture9 *)tex_dst2);
16134 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16136 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
16137 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16138 add_dirty_rect_test_draw(device);
16139 color = getPixelColor(device, 320, 240);
16140 ok(color_match(color, 0x0000ff00, 1),
16141 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16142 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16143 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16145 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
16146 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16147 add_dirty_rect_test_draw(device);
16148 color = getPixelColor(device, 320, 240);
16149 todo_wine ok(color_match(color, 0x00ff0000, 1),
16150 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16151 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16152 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16154 /* AddDirtyRect on the destination is ignored. */
16155 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
16156 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16157 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16158 (IDirect3DBaseTexture9 *)tex_dst2);
16159 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16160 add_dirty_rect_test_draw(device);
16161 color = getPixelColor(device, 320, 240);
16162 todo_wine ok(color_match(color, 0x00ff0000, 1),
16163 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16165 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16167 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
16168 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16169 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16170 (IDirect3DBaseTexture9 *)tex_dst2);
16171 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16172 add_dirty_rect_test_draw(device);
16173 color = getPixelColor(device, 320, 240);
16174 todo_wine ok(color_match(color, 0x00ff0000, 1),
16175 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16176 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16177 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16179 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
16180 * tracking is supported. */
16181 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
16182 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16183 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16184 (IDirect3DBaseTexture9 *)tex_dst2);
16185 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16186 add_dirty_rect_test_draw(device);
16187 color = getPixelColor(device, 320, 240);
16188 ok(color_match(color, 0x0000ff00, 1),
16189 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16190 color = getPixelColor(device, 1, 1);
16191 todo_wine ok(color_match(color, 0x00ff0000, 1),
16192 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16193 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16194 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16196 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
16197 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16198 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16199 (IDirect3DBaseTexture9 *)tex_dst2);
16200 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16201 add_dirty_rect_test_draw(device);
16202 color = getPixelColor(device, 1, 1);
16203 ok(color_match(color, 0x0000ff00, 1),
16204 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16206 /* Locks with NO_DIRTY_UPDATE are ignored. */
16207 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
16208 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16209 (IDirect3DBaseTexture9 *)tex_dst2);
16210 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16211 add_dirty_rect_test_draw(device);
16212 color = getPixelColor(device, 320, 240);
16213 todo_wine ok(color_match(color, 0x0000ff00, 1),
16214 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16215 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16216 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16218 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
16219 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
16220 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16221 (IDirect3DBaseTexture9 *)tex_dst2);
16222 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16223 add_dirty_rect_test_draw(device);
16224 color = getPixelColor(device, 320, 240);
16225 todo_wine ok(color_match(color, 0x0000ff00, 1),
16226 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16227 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16228 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16230 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
16231 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16232 (IDirect3DBaseTexture9 *)tex_dst2);
16233 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16234 add_dirty_rect_test_draw(device);
16235 color = getPixelColor(device, 320, 240);
16236 ok(color_match(color, 0x000000ff, 1),
16237 "Expected color 0x000000ff, got 0x%08x.\n", color);
16238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16239 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16241 /* Maps without either of these flags record a dirty rectangle. */
16242 fill_surface(surface_src_green, 0x00ffffff, 0);
16243 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16244 (IDirect3DBaseTexture9 *)tex_dst2);
16245 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16246 add_dirty_rect_test_draw(device);
16247 color = getPixelColor(device, 320, 240);
16248 ok(color_match(color, 0x00ffffff, 1),
16249 "Expected color 0x00ffffff, got 0x%08x.\n", color);
16250 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16251 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16253 /* Partial LockRect works just like a partial AddDirtyRect call. */
16254 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
16255 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16256 texel = locked_rect.pBits;
16257 for (i = 0; i < 64; i++)
16258 texel[i] = 0x00ff00ff;
16259 for (i = 1; i < 64; i++)
16260 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
16261 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
16262 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16263 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16264 (IDirect3DBaseTexture9 *)tex_dst2);
16265 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16266 add_dirty_rect_test_draw(device);
16267 color = getPixelColor(device, 320, 240);
16268 ok(color_match(color, 0x00ff00ff, 1),
16269 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
16270 color = getPixelColor(device, 1, 1);
16271 ok(color_match(color, 0x00ffffff, 1),
16272 "Expected color 0x00ffffff, got 0x%08x.\n", color);
16273 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16274 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16276 fill_surface(surface_src_red, 0x00ff0000, 0);
16277 fill_surface(surface_src_green, 0x0000ff00, 0);
16279 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
16280 (IDirect3DBaseTexture9 *)tex_dst1);
16281 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16282 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
16283 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16284 add_dirty_rect_test_draw(device);
16285 color = getPixelColor(device, 320, 240);
16286 ok(color_match(color, 0x0000ff00, 1),
16287 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16289 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16291 /* UpdateSurface ignores the missing dirty marker. */
16292 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
16293 (IDirect3DBaseTexture9 *)tex_dst2);
16294 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
16295 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
16296 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
16297 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16298 add_dirty_rect_test_draw(device);
16299 color = getPixelColor(device, 320, 240);
16300 ok(color_match(color, 0x0000ff00, 1),
16301 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16302 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16303 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16305 fill_surface(surface_managed, 0x00ff0000, 0);
16306 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
16307 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16308 add_dirty_rect_test_draw(device);
16309 color = getPixelColor(device, 320, 240);
16310 ok(color_match(color, 0x00ff0000, 1),
16311 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16312 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16313 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16315 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
16316 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
16317 add_dirty_rect_test_draw(device);
16318 color = getPixelColor(device, 320, 240);
16319 ok(color_match(color, 0x00ff0000, 1),
16320 "Expected color 0x00ff0000, got 0x%08x.\n", color);
16321 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16322 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16324 /* AddDirtyRect uploads the new contents.
16325 * Side note, not tested in the test: Partial surface updates work, and two separate
16326 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
16327 * untested. */
16328 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16329 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16330 add_dirty_rect_test_draw(device);
16331 color = getPixelColor(device, 320, 240);
16332 ok(color_match(color, 0x0000ff00, 1),
16333 "Expected color 0x0000ff00, got 0x%08x.\n", color);
16334 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16335 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16337 /* So does EvictManagedResources. */
16338 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
16339 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16340 hr = IDirect3DDevice9_EvictManagedResources(device);
16341 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
16342 add_dirty_rect_test_draw(device);
16343 color = getPixelColor(device, 320, 240);
16344 ok(color_match(color, 0x000000ff, 1),
16345 "Expected color 0x000000ff, got 0x%08x.\n", color);
16346 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16347 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
16349 /* AddDirtyRect on a locked texture is allowed. */
16350 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
16351 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
16352 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
16353 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16354 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
16355 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
16357 /* Redundant AddDirtyRect calls are ok. */
16358 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16359 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16360 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
16361 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
16363 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
16364 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
16365 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16366 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16367 IDirect3DSurface9_Release(surface_dst2);
16368 IDirect3DSurface9_Release(surface_managed);
16369 IDirect3DSurface9_Release(surface_src_red);
16370 IDirect3DSurface9_Release(surface_src_green);
16371 IDirect3DTexture9_Release(tex_src_red);
16372 IDirect3DTexture9_Release(tex_src_green);
16373 IDirect3DTexture9_Release(tex_dst1);
16374 IDirect3DTexture9_Release(tex_dst2);
16375 IDirect3DTexture9_Release(tex_managed);
16376 refcount = IDirect3DDevice9_Release(device);
16377 ok(!refcount, "Device has %u references left.\n", refcount);
16378 IDirect3D9_Release(d3d);
16379 DestroyWindow(window);
16382 START_TEST(visual)
16384 IDirect3DDevice9 *device_ptr;
16385 D3DCAPS9 caps;
16386 HRESULT hr;
16387 DWORD color;
16389 if (!(device_ptr = init_d3d9()))
16391 skip("Creating the device failed\n");
16392 return;
16395 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
16397 /* Check for the reliability of the returned data */
16398 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
16399 if(FAILED(hr))
16401 skip("Clear failed, can't assure correctness of the test results, skipping\n");
16402 goto cleanup;
16405 color = getPixelColor(device_ptr, 1, 1);
16406 if(color !=0x00ff0000)
16408 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
16409 goto cleanup;
16411 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
16413 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
16414 if(FAILED(hr))
16416 skip("Clear failed, can't assure correctness of the test results, skipping\n");
16417 goto cleanup;
16420 color = getPixelColor(device_ptr, 639, 479);
16421 if(color != 0x0000ddee)
16423 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
16424 goto cleanup;
16426 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
16428 /* Now execute the real tests */
16429 depth_clamp_test(device_ptr);
16430 stretchrect_test(device_ptr);
16431 lighting_test(device_ptr);
16432 clear_test(device_ptr);
16433 color_fill_test(device_ptr);
16434 fog_test(device_ptr);
16435 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
16437 test_cube_wrap(device_ptr);
16438 } else {
16439 skip("No cube texture support\n");
16441 z_range_test(device_ptr);
16442 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
16444 maxmip_test(device_ptr);
16446 else
16448 skip("No mipmap support\n");
16451 offscreen_test(device_ptr);
16452 ds_size_test(device_ptr);
16453 alpha_test(device_ptr);
16454 shademode_test(device_ptr);
16455 srgbtexture_test(device_ptr);
16456 release_buffer_test(device_ptr);
16457 float_texture_test(device_ptr);
16458 g16r16_texture_test(device_ptr);
16459 pixelshader_blending_test(device_ptr);
16460 texture_transform_flags_test(device_ptr);
16461 autogen_mipmap_test(device_ptr);
16462 fixed_function_decl_test(device_ptr);
16463 conditional_np2_repeat_test(device_ptr);
16464 fixed_function_bumpmap_test(device_ptr);
16465 pointsize_test(device_ptr);
16466 tssargtemp_test(device_ptr);
16467 np2_stretch_rect_test(device_ptr);
16468 yuv_color_test(device_ptr);
16469 yuv_layout_test(device_ptr);
16471 cleanup_device(device_ptr);
16472 device_ptr = NULL;
16474 zwriteenable_test();
16475 alphatest_test();
16476 viewport_test();
16477 test_constant_clamp_vs();
16478 test_compare_instructions();
16479 test_mova();
16480 loop_index_test();
16481 sincos_test();
16482 sgn_test();
16483 clip_planes_test();
16484 test_vshader_input();
16485 test_vshader_float16();
16486 stream_test();
16487 fog_with_shader_test();
16488 texbem_test();
16489 texdepth_test();
16490 texkill_test();
16491 x8l8v8u8_test();
16492 volume_v16u16_test();
16493 constant_clamp_ps_test();
16494 cnd_test();
16495 dp2add_ps_test();
16496 unbound_sampler_test();
16497 nested_loop_test();
16498 pretransformed_varying_test();
16499 vface_register_test();
16500 vpos_register_test();
16501 multiple_rendertargets_test();
16502 texop_test();
16503 texop_range_test();
16504 alphareplicate_test();
16505 dp3_alpha_test();
16506 depth_buffer_test();
16507 depth_buffer2_test();
16508 depth_blit_test();
16509 intz_test();
16510 shadow_test();
16511 fp_special_test();
16512 depth_bounds_test();
16513 srgbwrite_format_test();
16514 update_surface_test();
16515 multisample_get_rtdata_test();
16516 zenable_test();
16517 fog_special_test();
16518 volume_srgb_test();
16519 volume_dxt5_test();
16520 add_dirty_rect_test();
16521 multisampled_depth_buffer_test();
16522 resz_test();
16523 stencil_cull_test();
16525 cleanup:
16526 cleanup_device(device_ptr);