d3d9/tests: Rename a variable.
[wine.git] / dlls / d3d9 / tests / visual.c
blob761a3853b6ea4725d76b328e94928fd21f000dd5
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 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 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47 ShowWindow(ret, SW_SHOW);
48 return ret;
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 return TRUE;
63 /* Locks a given surface and returns the color at (x,y). It's the caller's
64 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
67 DWORD color;
68 HRESULT hr;
69 D3DSURFACE_DESC desc;
70 RECT rectToLock = {x, y, x+1, y+1};
71 D3DLOCKED_RECT lockedRect;
73 hr = IDirect3DSurface9_GetDesc(surface, &desc);
74 if(FAILED(hr)) /* This is not a test */
76 trace("Can't get the surface description, hr=%08x\n", hr);
77 return 0xdeadbeef;
80 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81 if(FAILED(hr)) /* This is not a test */
83 trace("Can't lock the surface, hr=%08x\n", hr);
84 return 0xdeadbeef;
86 switch(desc.Format) {
87 case D3DFMT_A8R8G8B8:
89 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90 break;
92 default:
93 trace("Error: unknown surface format: %d\n", desc.Format);
94 color = 0xdeadbeef;
95 break;
97 hr = IDirect3DSurface9_UnlockRect(surface);
98 if(FAILED(hr))
100 trace("Can't unlock the surface, hr=%08x\n", hr);
102 return color;
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
107 DWORD ret;
108 IDirect3DSurface9 *surf = NULL, *target = NULL;
109 HRESULT hr;
110 D3DLOCKED_RECT lockedRect;
111 RECT rectToLock = {x, y, x+1, y+1};
113 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
114 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115 if (FAILED(hr) || !surf)
117 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118 return 0xdeadbeef;
121 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122 if(FAILED(hr))
124 trace("Can't get the render target, hr=%08x\n", hr);
125 ret = 0xdeadbeed;
126 goto out;
129 hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130 if (FAILED(hr))
132 trace("Can't read the render target data, hr=%08x\n", hr);
133 ret = 0xdeadbeec;
134 goto out;
137 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138 if(FAILED(hr))
140 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141 ret = 0xdeadbeeb;
142 goto out;
145 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146 * really important for these tests
148 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149 hr = IDirect3DSurface9_UnlockRect(surf);
150 if(FAILED(hr))
152 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
155 out:
156 if(target) IDirect3DSurface9_Release(target);
157 if(surf) IDirect3DSurface9_Release(surf);
158 return ret;
161 static IDirect3DDevice9 *init_d3d9(void)
163 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164 IDirect3D9 *d3d9_ptr = 0;
165 IDirect3DDevice9 *device_ptr = 0;
166 D3DPRESENT_PARAMETERS present_parameters;
167 HRESULT hr;
168 D3DADAPTER_IDENTIFIER9 identifier;
170 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172 if (!d3d9_create) return NULL;
174 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175 if (!d3d9_ptr)
177 skip("could not create D3D9\n");
178 return NULL;
181 ZeroMemory(&present_parameters, sizeof(present_parameters));
182 present_parameters.Windowed = TRUE;
183 present_parameters.hDeviceWindow = create_window();
184 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185 present_parameters.BackBufferWidth = 640;
186 present_parameters.BackBufferHeight = 480;
187 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188 present_parameters.EnableAutoDepthStencil = TRUE;
189 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
191 memset(&identifier, 0, sizeof(identifier));
192 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194 trace("Driver string: \"%s\"\n", identifier.Driver);
195 trace("Description string: \"%s\"\n", identifier.Description);
196 ok(identifier.Description[0] != '\0', "Empty driver description\n");
197 trace("Device name string: \"%s\"\n", identifier.DeviceName);
198 ok(identifier.DeviceName[0] != '\0', "Empty device name\n");
199 trace("Driver version %d.%d.%d.%d\n",
200 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
203 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
204 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
205 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
206 "Failed to create a device, hr %#x.\n", hr);
208 return device_ptr;
211 struct vertex
213 float x, y, z;
214 DWORD diffuse;
217 struct tvertex
219 float x, y, z, rhw;
220 DWORD diffuse;
223 struct nvertex
225 float x, y, z;
226 float nx, ny, nz;
227 DWORD diffuse;
230 static void lighting_test(IDirect3DDevice9 *device)
232 HRESULT hr;
233 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
234 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
235 DWORD color;
236 D3DMATERIAL9 material, old_material;
237 DWORD cop, carg;
238 DWORD old_colorwrite;
240 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
241 0.0f, 1.0f, 0.0f, 0.0f,
242 0.0f, 0.0f, 1.0f, 0.0f,
243 0.0f, 0.0f, 0.0f, 1.0f };
245 struct vertex unlitquad[] =
247 {-1.0f, -1.0f, 0.1f, 0xffff0000},
248 {-1.0f, 0.0f, 0.1f, 0xffff0000},
249 { 0.0f, 0.0f, 0.1f, 0xffff0000},
250 { 0.0f, -1.0f, 0.1f, 0xffff0000},
252 struct vertex litquad[] =
254 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
255 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
256 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
257 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
259 struct nvertex unlitnquad[] =
261 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
262 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
263 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
264 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
266 struct nvertex litnquad[] =
268 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
269 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
270 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
271 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
273 WORD Indices[] = {0, 1, 2, 2, 3, 0};
275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
276 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
278 /* Setup some states that may cause issues */
279 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
280 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
281 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
282 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
283 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
286 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
288 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
290 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
296 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
300 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
301 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &old_colorwrite);
302 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306 hr = IDirect3DDevice9_SetFVF(device, 0);
307 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309 hr = IDirect3DDevice9_SetFVF(device, fvf);
310 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312 hr = IDirect3DDevice9_BeginScene(device);
313 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
314 if(hr == D3D_OK)
316 /* No lights are defined... That means, lit vertices should be entirely black */
317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
318 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
319 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
320 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
321 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
324 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
327 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329 hr = IDirect3DDevice9_SetFVF(device, nfvf);
330 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
333 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
334 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
335 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
336 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
340 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
341 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
342 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344 IDirect3DDevice9_EndScene(device);
345 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
348 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
349 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
350 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
351 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
352 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
353 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
354 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
355 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
357 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
360 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
361 memset(&material, 0, sizeof(material));
362 material.Diffuse.r = 0.0;
363 material.Diffuse.g = 0.0;
364 material.Diffuse.b = 0.0;
365 material.Diffuse.a = 1.0;
366 material.Ambient.r = 0.0;
367 material.Ambient.g = 0.0;
368 material.Ambient.b = 0.0;
369 material.Ambient.a = 0.0;
370 material.Specular.r = 0.0;
371 material.Specular.g = 0.0;
372 material.Specular.b = 0.0;
373 material.Specular.a = 0.0;
374 material.Emissive.r = 0.0;
375 material.Emissive.g = 0.0;
376 material.Emissive.b = 0.0;
377 material.Emissive.a = 0.0;
378 material.Power = 0.0;
379 IDirect3DDevice9_SetMaterial(device, &material);
380 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
383 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
385 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
388 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
389 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
390 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
392 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
393 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
394 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396 hr = IDirect3DDevice9_BeginScene(device);
397 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
398 if(SUCCEEDED(hr)) {
399 struct vertex lighting_test[] = {
400 {-1.0, -1.0, 0.1, 0x8000ff00},
401 { 1.0, -1.0, 0.1, 0x80000000},
402 {-1.0, 1.0, 0.1, 0x8000ff00},
403 { 1.0, 1.0, 0.1, 0x80000000}
405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
406 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
408 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410 hr = IDirect3DDevice9_EndScene(device);
411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
414 color = getPixelColor(device, 320, 240);
415 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
416 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
419 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
421 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
423 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
425 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, old_colorwrite);
427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
428 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
434 static void clear_test(IDirect3DDevice9 *device)
436 /* Tests the correctness of clearing parameters */
437 HRESULT hr;
438 D3DRECT rect[2];
439 D3DRECT rect_negneg;
440 DWORD color;
441 D3DVIEWPORT9 old_vp, vp;
442 RECT scissor;
443 DWORD oldColorWrite;
444 BOOL invalid_clear_failed = FALSE;
446 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
449 /* Positive x, negative y */
450 rect[0].x1 = 0;
451 rect[0].y1 = 480;
452 rect[0].x2 = 320;
453 rect[0].y2 = 240;
455 /* Positive x, positive y */
456 rect[1].x1 = 0;
457 rect[1].y1 = 0;
458 rect[1].x2 = 320;
459 rect[1].y2 = 240;
460 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461 * returns D3D_OK, but ignores the rectangle silently
463 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
467 /* negative x, negative y */
468 rect_negneg.x1 = 640;
469 rect_negneg.y1 = 240;
470 rect_negneg.x2 = 320;
471 rect_negneg.y2 = 0;
472 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
476 color = getPixelColor(device, 160, 360); /* lower left quad */
477 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478 color = getPixelColor(device, 160, 120); /* upper left quad */
479 if(invalid_clear_failed) {
480 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482 } else {
483 /* If the negative rectangle was dropped silently, the correct ones are cleared */
484 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
486 color = getPixelColor(device, 480, 360); /* lower right quad */
487 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488 color = getPixelColor(device, 480, 120); /* upper right quad */
489 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
491 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
493 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494 * clear the red quad in the top left part of the render target. For some reason it
495 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498 * pick some obvious value
500 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
503 /* Test how the viewport affects clears */
504 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
509 vp.X = 160;
510 vp.Y = 120;
511 vp.Width = 160;
512 vp.Height = 120;
513 vp.MinZ = 0.0;
514 vp.MaxZ = 1.0;
515 hr = IDirect3DDevice9_SetViewport(device, &vp);
516 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
520 vp.X = 320;
521 vp.Y = 240;
522 vp.Width = 320;
523 vp.Height = 240;
524 vp.MinZ = 0.0;
525 vp.MaxZ = 1.0;
526 hr = IDirect3DDevice9_SetViewport(device, &vp);
527 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528 rect[0].x1 = 160;
529 rect[0].y1 = 120;
530 rect[0].x2 = 480;
531 rect[0].y2 = 360;
532 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
535 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
538 color = getPixelColor(device, 158, 118);
539 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540 color = getPixelColor(device, 162, 118);
541 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542 color = getPixelColor(device, 158, 122);
543 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544 color = getPixelColor(device, 162, 122);
545 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
547 color = getPixelColor(device, 318, 238);
548 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549 color = getPixelColor(device, 322, 238);
550 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551 color = getPixelColor(device, 318, 242);
552 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553 color = getPixelColor(device, 322, 242);
554 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
556 color = getPixelColor(device, 478, 358);
557 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558 color = getPixelColor(device, 482, 358);
559 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560 color = getPixelColor(device, 478, 362);
561 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562 color = getPixelColor(device, 482, 362);
563 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
565 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
567 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570 scissor.left = 160;
571 scissor.right = 480;
572 scissor.top = 120;
573 scissor.bottom = 360;
574 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
587 color = getPixelColor(device, 158, 118);
588 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589 color = getPixelColor(device, 162, 118);
590 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591 color = getPixelColor(device, 158, 122);
592 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593 color = getPixelColor(device, 162, 122);
594 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
596 color = getPixelColor(device, 158, 358);
597 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598 color = getPixelColor(device, 162, 358);
599 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600 color = getPixelColor(device, 158, 358);
601 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602 color = getPixelColor(device, 162, 362);
603 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
605 color = getPixelColor(device, 478, 118);
606 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607 color = getPixelColor(device, 478, 122);
608 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609 color = getPixelColor(device, 482, 122);
610 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611 color = getPixelColor(device, 482, 358);
612 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
614 color = getPixelColor(device, 478, 358);
615 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616 color = getPixelColor(device, 478, 362);
617 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618 color = getPixelColor(device, 482, 358);
619 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620 color = getPixelColor(device, 482, 362);
621 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
623 color = getPixelColor(device, 318, 238);
624 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625 color = getPixelColor(device, 318, 242);
626 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627 color = getPixelColor(device, 322, 238);
628 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629 color = getPixelColor(device, 322, 242);
630 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
632 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
634 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
639 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
649 /* Colorwriteenable does not affect the clear */
650 color = getPixelColor(device, 320, 240);
651 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
653 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
656 static void color_fill_test(IDirect3DDevice9 *device)
658 HRESULT hr;
659 IDirect3DSurface9 *backbuffer = NULL;
660 IDirect3DSurface9 *rt_surface = NULL;
661 IDirect3DSurface9 *offscreen_surface = NULL;
662 DWORD fill_color, color;
664 /* Test ColorFill on a the backbuffer (should pass) */
665 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667 if(backbuffer)
669 fill_color = 0x112233;
670 hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
673 color = getPixelColor(device, 0, 0);
674 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
676 IDirect3DSurface9_Release(backbuffer);
679 /* Test ColorFill on a render target surface (should pass) */
680 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682 if(rt_surface)
684 fill_color = 0x445566;
685 hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
688 color = getPixelColorFromSurface(rt_surface, 0, 0);
689 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
691 IDirect3DSurface9_Release(rt_surface);
694 /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698 if(offscreen_surface)
700 fill_color = 0x778899;
701 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
704 color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
707 IDirect3DSurface9_Release(offscreen_surface);
710 /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711 offscreen_surface = NULL;
712 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715 if(offscreen_surface)
717 hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
720 IDirect3DSurface9_Release(offscreen_surface);
724 typedef struct {
725 float in[4];
726 DWORD out;
727 } test_data_t;
730 * c7 mova ARGB mov ARGB
731 * -2.4 -2 0x00ffff00 -3 0x00ff0000
732 * -1.6 -2 0x00ffff00 -2 0x00ffff00
733 * -0.4 0 0x0000ffff -1 0x0000ff00
734 * 0.4 0 0x0000ffff 0 0x0000ffff
735 * 1.6 2 0x00ff00ff 1 0x000000ff
736 * 2.4 2 0x00ff00ff 2 0x00ff00ff
738 static void test_mova(IDirect3DDevice9 *device)
740 static const DWORD mova_test[] = {
741 0xfffe0200, /* vs_2_0 */
742 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
743 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
744 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
745 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
746 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
747 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
748 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
749 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
750 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
751 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
752 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
753 0x0000ffff /* END */
755 static const DWORD mov_test[] = {
756 0xfffe0101, /* vs_1_1 */
757 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
758 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
759 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
760 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
761 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
762 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
763 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
764 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
765 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
766 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
767 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
768 0x0000ffff /* END */
771 static const test_data_t test_data[2][6] = {
773 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
781 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
790 static const float quad[][3] = {
791 {-1.0f, -1.0f, 0.0f},
792 {-1.0f, 1.0f, 0.0f},
793 { 1.0f, -1.0f, 0.0f},
794 { 1.0f, 1.0f, 0.0f},
797 static const D3DVERTEXELEMENT9 decl_elements[] = {
798 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799 D3DDECL_END()
802 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803 IDirect3DVertexShader9 *mova_shader = NULL;
804 IDirect3DVertexShader9 *mov_shader = NULL;
805 HRESULT hr;
806 UINT i, j;
808 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
817 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819 for(j = 0; j < 2; ++j)
821 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
823 DWORD color;
825 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
828 hr = IDirect3DDevice9_BeginScene(device);
829 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
834 hr = IDirect3DDevice9_EndScene(device);
835 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
837 color = getPixelColor(device, 320, 240);
838 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
841 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
844 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
847 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
851 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
854 IDirect3DVertexDeclaration9_Release(vertex_declaration);
855 IDirect3DVertexShader9_Release(mova_shader);
856 IDirect3DVertexShader9_Release(mov_shader);
859 struct sVertex {
860 float x, y, z;
861 DWORD diffuse;
862 DWORD specular;
865 struct sVertexT {
866 float x, y, z, rhw;
867 DWORD diffuse;
868 DWORD specular;
871 static void fog_test(IDirect3DDevice9 *device)
873 HRESULT hr;
874 D3DCOLOR color;
875 float start = 0.0f, end = 1.0f;
876 D3DCAPS9 caps;
877 int i;
879 /* Gets full z based fog with linear fog, no fog with specular color */
880 struct sVertex untransformed_1[] = {
881 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
882 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
883 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
884 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
886 /* Ok, I am too lazy to deal with transform matrices */
887 struct sVertex untransformed_2[] = {
888 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
889 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
890 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
891 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
893 /* Untransformed ones. Give them a different diffuse color to make the test look
894 * nicer. It also makes making sure that they are drawn correctly easier.
896 struct sVertexT transformed_1[] = {
897 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
898 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
899 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
900 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
902 struct sVertexT transformed_2[] = {
903 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
904 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
905 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
906 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
908 struct vertex rev_fog_quads[] = {
909 {-1.0, -1.0, 0.1, 0x000000ff},
910 {-1.0, 0.0, 0.1, 0x000000ff},
911 { 0.0, 0.0, 0.1, 0x000000ff},
912 { 0.0, -1.0, 0.1, 0x000000ff},
914 { 0.0, -1.0, 0.9, 0x000000ff},
915 { 0.0, 0.0, 0.9, 0x000000ff},
916 { 1.0, 0.0, 0.9, 0x000000ff},
917 { 1.0, -1.0, 0.9, 0x000000ff},
919 { 0.0, 0.0, 0.4, 0x000000ff},
920 { 0.0, 1.0, 0.4, 0x000000ff},
921 { 1.0, 1.0, 0.4, 0x000000ff},
922 { 1.0, 0.0, 0.4, 0x000000ff},
924 {-1.0, 0.0, 0.7, 0x000000ff},
925 {-1.0, 1.0, 0.7, 0x000000ff},
926 { 0.0, 1.0, 0.7, 0x000000ff},
927 { 0.0, 0.0, 0.7, 0x000000ff},
929 WORD Indices[] = {0, 1, 2, 2, 3, 0};
931 memset(&caps, 0, sizeof(caps));
932 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
933 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
934 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
935 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
937 /* Setup initial states: No lighting, fog on, fog color */
938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
939 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
941 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
943 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
945 /* First test: Both table fog and vertex fog off */
946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
949 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
951 /* Start = 0, end = 1. Should be default, but set them */
952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
953 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
955 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
957 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
960 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
961 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
962 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
964 sizeof(untransformed_1[0]));
965 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
967 /* That makes it use the Z value */
968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
969 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
970 /* Untransformed, vertex fog != none (or table fog != none):
971 * Use the Z value as input into the equation
973 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
975 sizeof(untransformed_2[0]));
976 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
978 /* transformed verts */
979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
980 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
981 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
982 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
983 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
984 sizeof(transformed_1[0]));
985 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
988 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
989 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
990 * equation
992 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
993 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
994 sizeof(transformed_2[0]));
995 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
997 hr = IDirect3DDevice9_EndScene(device);
998 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1000 else
1002 ok(FALSE, "BeginScene failed\n");
1005 color = getPixelColor(device, 160, 360);
1006 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1007 color = getPixelColor(device, 160, 120);
1008 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1009 color = getPixelColor(device, 480, 120);
1010 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1011 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1013 color = getPixelColor(device, 480, 360);
1014 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1016 else
1018 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1019 * The settings above result in no fogging with vertex fog
1021 color = getPixelColor(device, 480, 120);
1022 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1023 trace("Info: Table fog not supported by this device\n");
1025 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1027 /* Now test the special case fogstart == fogend */
1028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1029 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1031 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1033 start = 512;
1034 end = 512;
1035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1036 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1038 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1043 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1047 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1048 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1049 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1050 * The third transformed quad remains unfogged because the fogcoords are read from the specular
1051 * color and has fixed fogstart and fogend.
1053 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1,
1055 sizeof(untransformed_1[0]));
1056 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1058 2 /*PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2,
1059 sizeof(untransformed_2[0]));
1060 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1062 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1063 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1064 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1065 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1066 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1067 sizeof(transformed_1[0]));
1068 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1070 hr = IDirect3DDevice9_EndScene(device);
1071 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1073 else
1075 ok(FALSE, "BeginScene failed\n");
1077 color = getPixelColor(device, 160, 360);
1078 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1079 color = getPixelColor(device, 160, 120);
1080 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1081 color = getPixelColor(device, 480, 120);
1082 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1083 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1085 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1086 * but without shaders it seems to work everywhere
1088 end = 0.2;
1089 start = 0.8;
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);
1094 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1095 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1097 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1098 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1099 * so skip this for now
1101 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1102 const char *mode = (i ? "table" : "vertex");
1103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1104 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1106 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1108 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1109 hr = IDirect3DDevice9_BeginScene(device);
1110 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1111 if(SUCCEEDED(hr)) {
1112 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1113 4, 5, 6, 6, 7, 4,
1114 8, 9, 10, 10, 11, 8,
1115 12, 13, 14, 14, 15, 12};
1117 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1118 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1119 sizeof(rev_fog_quads[0]));
1120 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1122 hr = IDirect3DDevice9_EndScene(device);
1123 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1125 color = getPixelColor(device, 160, 360);
1126 ok(color_match(color, 0x0000ff00, 1),
1127 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1129 color = getPixelColor(device, 160, 120);
1130 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1131 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1133 color = getPixelColor(device, 480, 120);
1134 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1135 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1137 color = getPixelColor(device, 480, 360);
1138 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1140 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1142 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1143 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1144 break;
1147 /* Turn off the fog master switch to avoid confusing other tests */
1148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1149 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1150 start = 0.0;
1151 end = 1.0;
1152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1153 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1155 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1157 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1159 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1162 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1163 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1164 * regardless of the actual addressing mode set. The way this test works is
1165 * that we sample in one of the corners of the cubemap with filtering enabled,
1166 * and check the interpolated color. There are essentially two reasonable
1167 * things an implementation can do: Either pick one of the faces and
1168 * interpolate the edge texel with itself (i.e., clamp within the face), or
1169 * interpolate between the edge texels of the three involved faces. It should
1170 * never involve the border color or the other side (texcoord wrapping) of a
1171 * face in the interpolation. */
1172 static void test_cube_wrap(IDirect3DDevice9 *device)
1174 static const float quad[][6] = {
1175 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1176 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1177 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1178 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1181 static const D3DVERTEXELEMENT9 decl_elements[] = {
1182 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1183 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1184 D3DDECL_END()
1187 static const struct {
1188 D3DTEXTUREADDRESS mode;
1189 const char *name;
1190 } address_modes[] = {
1191 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1192 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1193 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1194 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1195 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1198 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1199 IDirect3DCubeTexture9 *texture = NULL;
1200 IDirect3DSurface9 *surface = NULL;
1201 IDirect3DSurface9 *face_surface;
1202 D3DLOCKED_RECT locked_rect;
1203 HRESULT hr;
1204 UINT x;
1205 INT y, face;
1207 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1208 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1209 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1210 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1212 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1213 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1214 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1216 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1217 D3DPOOL_DEFAULT, &texture, NULL);
1218 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1220 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1221 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1223 for (y = 0; y < 128; ++y)
1225 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1226 for (x = 0; x < 64; ++x)
1228 *ptr++ = 0xff0000ff;
1230 for (x = 64; x < 128; ++x)
1232 *ptr++ = 0xffff0000;
1236 hr = IDirect3DSurface9_UnlockRect(surface);
1237 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1239 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1240 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1242 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1243 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1245 IDirect3DSurface9_Release(face_surface);
1247 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1248 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1250 for (y = 0; y < 128; ++y)
1252 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1253 for (x = 0; x < 64; ++x)
1255 *ptr++ = 0xffff0000;
1257 for (x = 64; x < 128; ++x)
1259 *ptr++ = 0xff0000ff;
1263 hr = IDirect3DSurface9_UnlockRect(surface);
1264 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1266 /* Create cube faces */
1267 for (face = 1; face < 6; ++face)
1269 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1270 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1272 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1273 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1275 IDirect3DSurface9_Release(face_surface);
1278 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1279 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1281 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1282 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1283 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1284 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1285 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1286 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1291 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1293 DWORD color;
1295 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1296 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1297 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1298 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1300 hr = IDirect3DDevice9_BeginScene(device);
1301 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1304 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1306 hr = IDirect3DDevice9_EndScene(device);
1307 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1309 color = getPixelColor(device, 320, 240);
1310 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1311 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1312 color, address_modes[x].name);
1314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1318 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1321 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1322 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1324 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1325 IDirect3DCubeTexture9_Release(texture);
1326 IDirect3DSurface9_Release(surface);
1329 static void offscreen_test(IDirect3DDevice9 *device)
1331 HRESULT hr;
1332 IDirect3DTexture9 *offscreenTexture = NULL;
1333 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1334 DWORD color;
1336 static const float quad[][5] = {
1337 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1338 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1339 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1340 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1344 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1346 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1347 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1348 if(!offscreenTexture) {
1349 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1350 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1351 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1352 if(!offscreenTexture) {
1353 skip("Cannot create an offscreen render target\n");
1354 goto out;
1358 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1359 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1360 if(!backbuffer) {
1361 goto out;
1364 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1365 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1366 if(!offscreen) {
1367 goto out;
1370 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1371 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1373 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1374 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1375 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1376 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1377 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1378 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1379 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1380 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1382 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1384 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1385 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1386 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1388 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1390 /* Draw without textures - Should result in a white quad */
1391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1392 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1394 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1395 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1396 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1397 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1399 /* This time with the texture */
1400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1401 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1403 IDirect3DDevice9_EndScene(device);
1406 /* Center quad - should be white */
1407 color = getPixelColor(device, 320, 240);
1408 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1409 /* Some quad in the cleared part of the texture */
1410 color = getPixelColor(device, 170, 240);
1411 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1412 /* Part of the originally cleared back buffer */
1413 color = getPixelColor(device, 10, 10);
1414 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1415 if(0) {
1416 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1417 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1418 * the offscreen rendering mode this test would succeed or fail
1420 color = getPixelColor(device, 10, 470);
1421 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1424 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1426 out:
1427 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1430 /* restore things */
1431 if(backbuffer) {
1432 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1433 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1434 IDirect3DSurface9_Release(backbuffer);
1436 if(offscreenTexture) {
1437 IDirect3DTexture9_Release(offscreenTexture);
1439 if(offscreen) {
1440 IDirect3DSurface9_Release(offscreen);
1444 /* This test tests fog in combination with shaders.
1445 * What's tested: linear fog (vertex and table) with pixel shader
1446 * linear table fog with non foggy vertex shader
1447 * vertex fog with foggy vertex shader, non-linear
1448 * fog with shader, non-linear fog with foggy shader,
1449 * linear table fog with foggy shader
1451 static void fog_with_shader_test(IDirect3DDevice9 *device)
1453 HRESULT hr;
1454 DWORD color;
1455 union {
1456 float f;
1457 DWORD i;
1458 } start, end;
1459 unsigned int i, j;
1461 /* basic vertex shader without fog computation ("non foggy") */
1462 static const DWORD vertex_shader_code1[] = {
1463 0xfffe0101, /* vs_1_1 */
1464 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1465 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1466 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1467 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1468 0x0000ffff
1470 /* basic vertex shader with reversed fog computation ("foggy") */
1471 static const DWORD vertex_shader_code2[] = {
1472 0xfffe0101, /* vs_1_1 */
1473 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1474 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1475 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1476 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1477 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1478 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1479 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1480 0x0000ffff
1482 /* basic pixel shader */
1483 static const DWORD pixel_shader_code[] = {
1484 0xffff0101, /* ps_1_1 */
1485 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1486 0x0000ffff
1489 static struct vertex quad[] = {
1490 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1491 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1492 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1493 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1496 static const D3DVERTEXELEMENT9 decl_elements[] = {
1497 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1498 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1499 D3DDECL_END()
1502 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1503 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1504 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1506 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1507 static const struct test_data_t {
1508 int vshader;
1509 int pshader;
1510 D3DFOGMODE vfog;
1511 D3DFOGMODE tfog;
1512 unsigned int color[11];
1513 } test_data[] = {
1514 /* only pixel shader: */
1515 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1516 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1517 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1518 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1519 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1520 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1521 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1522 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1523 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1525 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1531 /* vertex shader */
1532 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1533 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1534 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1535 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1536 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1537 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1538 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1539 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1540 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1542 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1543 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1544 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1545 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1546 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1547 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1549 /* vertex shader and pixel shader */
1550 /* The next 4 tests would read the fog coord output, but it isn't available.
1551 * The result is a fully fogged quad, no matter what the Z coord is. This is on
1552 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1553 * These tests should be disabled if some other hardware behaves differently
1555 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1556 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1557 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1558 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1559 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1560 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1561 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1562 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1563 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1564 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1565 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1566 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1568 /* These use the Z coordinate with linear table fog */
1569 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1570 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1571 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1572 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1573 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1574 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1575 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1576 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1577 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1578 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1579 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1580 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1582 /* Non-linear table fog without fog coord */
1583 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1584 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1585 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1586 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1587 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1588 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1590 #if 0 /* FIXME: these fail on GeForce 8500 */
1591 /* foggy vertex shader */
1592 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1593 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1594 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1595 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1596 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1597 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1598 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1599 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1600 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1601 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1602 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1603 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 #endif
1606 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1607 * all using the fixed fog-coord linear fog
1609 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1610 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1611 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1612 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1613 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1614 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1615 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1616 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1617 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1618 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1619 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1620 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1622 /* These use table fog. Here the shader-provided fog coordinate is
1623 * ignored and the z coordinate used instead
1625 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1626 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1627 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1628 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1629 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1630 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1631 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1632 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1633 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1636 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1637 start.f=0.1f;
1638 end.f=0.9f;
1640 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1641 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1642 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1643 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1644 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1645 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1646 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1647 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1649 /* Setup initial states: No lighting, fog on, fog color */
1650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1651 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1653 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1655 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1656 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1657 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1660 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1662 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1664 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1666 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1668 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1670 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1672 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1673 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1674 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1675 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1677 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1679 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1681 for(j=0; j < 11; j++)
1683 /* Don't use the whole zrange to prevent rounding errors */
1684 quad[0].z = 0.001f + (float)j / 10.02f;
1685 quad[1].z = 0.001f + (float)j / 10.02f;
1686 quad[2].z = 0.001f + (float)j / 10.02f;
1687 quad[3].z = 0.001f + (float)j / 10.02f;
1689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1690 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1692 hr = IDirect3DDevice9_BeginScene(device);
1693 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1696 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1698 hr = IDirect3DDevice9_EndScene(device);
1699 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1701 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1702 color = getPixelColor(device, 128, 240);
1703 ok(color_match(color, test_data[i].color[j], 13),
1704 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1705 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1707 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1711 /* reset states */
1712 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1713 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1714 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1715 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1716 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1717 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1719 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1721 IDirect3DVertexShader9_Release(vertex_shader[1]);
1722 IDirect3DVertexShader9_Release(vertex_shader[2]);
1723 IDirect3DPixelShader9_Release(pixel_shader[1]);
1724 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1727 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1728 unsigned int i, x, y;
1729 HRESULT hr;
1730 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1731 D3DLOCKED_RECT locked_rect;
1733 /* Generate the textures */
1734 for(i=0; i<2; i++)
1736 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1737 D3DPOOL_MANAGED, &texture[i], NULL);
1738 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1740 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1741 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742 for (y = 0; y < 128; ++y)
1744 if(i)
1745 { /* Set up black texture with 2x2 texel white spot in the middle */
1746 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1747 for (x = 0; x < 128; ++x)
1749 if(y>62 && y<66 && x>62 && x<66)
1750 *ptr++ = 0xffffffff;
1751 else
1752 *ptr++ = 0xff000000;
1755 else
1756 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1757 * (if multiplied with bumpenvmat)
1759 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1760 for (x = 0; x < 128; ++x)
1762 if(abs(x-64)>abs(y-64))
1764 if(x < 64)
1765 *ptr++ = 0xc000;
1766 else
1767 *ptr++ = 0x4000;
1769 else
1771 if(y < 64)
1772 *ptr++ = 0x0040;
1773 else
1774 *ptr++ = 0x00c0;
1779 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1780 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1782 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1783 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1785 /* Disable texture filtering */
1786 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1787 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1788 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1789 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1791 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1792 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1793 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1794 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1798 /* test the behavior of the texbem instruction
1799 * with normal 2D and projective 2D textures
1801 static void texbem_test(IDirect3DDevice9 *device)
1803 HRESULT hr;
1804 DWORD color;
1805 int i;
1807 static const DWORD pixel_shader_code[] = {
1808 0xffff0101, /* ps_1_1*/
1809 0x00000042, 0xb00f0000, /* tex t0*/
1810 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1811 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1812 0x0000ffff
1814 static const DWORD double_texbem_code[] = {
1815 0xffff0103, /* ps_1_3 */
1816 0x00000042, 0xb00f0000, /* tex t0 */
1817 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1818 0x00000042, 0xb00f0002, /* tex t2 */
1819 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1820 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1821 0x0000ffff /* end */
1825 static const float quad[][7] = {
1826 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1827 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1828 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1829 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1831 static const float quad_proj[][9] = {
1832 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1833 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1834 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1835 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1838 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1839 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842 D3DDECL_END()
1844 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1845 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1846 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1847 D3DDECL_END()
1848 } };
1850 /* use asymmetric matrix to test loading */
1851 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1853 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1854 IDirect3DPixelShader9 *pixel_shader = NULL;
1855 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1856 D3DLOCKED_RECT locked_rect;
1858 generate_bumpmap_textures(device);
1860 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1861 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1862 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1863 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1864 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1866 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1867 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1869 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1872 for(i=0; i<2; i++)
1874 if(i)
1876 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1877 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1880 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1881 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1882 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1883 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1885 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1886 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1887 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1888 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1890 hr = IDirect3DDevice9_BeginScene(device);
1891 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1893 if(!i)
1894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1895 else
1896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1897 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1899 hr = IDirect3DDevice9_EndScene(device);
1900 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1902 color = getPixelColor(device, 320-32, 240);
1903 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1904 color = getPixelColor(device, 320+32, 240);
1905 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906 color = getPixelColor(device, 320, 240-32);
1907 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1908 color = getPixelColor(device, 320, 240+32);
1909 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1911 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1912 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1914 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1915 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1916 IDirect3DPixelShader9_Release(pixel_shader);
1918 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1919 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1920 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1923 /* clean up */
1924 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1925 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1927 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1928 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1930 for(i=0; i<2; i++)
1932 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1933 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1934 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1935 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1936 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1937 IDirect3DTexture9_Release(texture);
1940 /* Test double texbem */
1941 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1942 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1943 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1944 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1945 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1946 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1947 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1948 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1950 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1951 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1952 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1953 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1955 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1956 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1958 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1959 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1960 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1961 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1962 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1963 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1966 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1967 #define tex 0x00ff0000
1968 #define tex1 0x0000ff00
1969 #define origin 0x000000ff
1970 static const DWORD pixel_data[] = {
1971 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1974 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1975 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1976 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1977 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1978 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1980 #undef tex1
1981 #undef tex2
1982 #undef origin
1984 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1985 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1986 for(i = 0; i < 8; i++) {
1987 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1989 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1990 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1993 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1994 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1995 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1996 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1997 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1998 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1999 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2000 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2001 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2002 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2004 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2006 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
2007 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
2008 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2009 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2011 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2012 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2013 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2014 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2017 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
2018 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
2019 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2020 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2021 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2022 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2023 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2025 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2026 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2028 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2029 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2030 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2031 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2032 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2033 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2034 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2035 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2036 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2037 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2038 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2039 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2040 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2042 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2043 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2045 hr = IDirect3DDevice9_BeginScene(device);
2046 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2047 if(SUCCEEDED(hr)) {
2048 static const float double_quad[] = {
2049 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2050 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2051 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2052 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
2055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2056 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2057 hr = IDirect3DDevice9_EndScene(device);
2058 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2060 color = getPixelColor(device, 320, 240);
2061 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2063 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2065 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2067 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2069 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2070 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2071 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2072 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2075 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2077 IDirect3DPixelShader9_Release(pixel_shader);
2078 IDirect3DTexture9_Release(texture);
2079 IDirect3DTexture9_Release(texture1);
2080 IDirect3DTexture9_Release(texture2);
2083 static void z_range_test(IDirect3DDevice9 *device)
2085 const struct vertex quad[] =
2087 {-1.0f, 0.0f, 1.1f, 0xffff0000},
2088 {-1.0f, 1.0f, 1.1f, 0xffff0000},
2089 { 1.0f, 0.0f, -1.1f, 0xffff0000},
2090 { 1.0f, 1.0f, -1.1f, 0xffff0000},
2092 const struct vertex quad2[] =
2094 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
2095 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
2096 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
2097 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
2100 const struct tvertex quad3[] =
2102 { 0, 240, 1.1f, 1.0, 0xffffff00},
2103 { 0, 480, 1.1f, 1.0, 0xffffff00},
2104 { 640, 240, -1.1f, 1.0, 0xffffff00},
2105 { 640, 480, -1.1f, 1.0, 0xffffff00},
2107 const struct tvertex quad4[] =
2109 { 0, 240, 1.1f, 1.0, 0xff00ff00},
2110 { 0, 480, 1.1f, 1.0, 0xff00ff00},
2111 { 640, 240, -1.1f, 1.0, 0xff00ff00},
2112 { 640, 480, -1.1f, 1.0, 0xff00ff00},
2114 HRESULT hr;
2115 DWORD color;
2116 IDirect3DVertexShader9 *shader;
2117 IDirect3DVertexDeclaration9 *decl;
2118 D3DCAPS9 caps;
2119 const DWORD shader_code[] = {
2120 0xfffe0101, /* vs_1_1 */
2121 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2122 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2123 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2124 0x0000ffff /* end */
2126 static const D3DVERTEXELEMENT9 decl_elements[] = {
2127 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2128 D3DDECL_END()
2131 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2133 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2134 * then call Present. Then clear the color buffer to make sure it has some defined content
2135 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2136 * by the depth value.
2138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2139 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2140 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2141 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2143 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2148 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2152 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2153 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2154 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2156 hr = IDirect3DDevice9_BeginScene(device);
2157 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2158 if(hr == D3D_OK)
2160 /* Test the untransformed vertex path */
2161 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2162 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2164 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2166 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2168 /* Test the transformed vertex path */
2169 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2170 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2172 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2173 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2175 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2177 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2179 hr = IDirect3DDevice9_EndScene(device);
2180 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2183 /* Do not test the exact corner pixels, but go pretty close to them */
2185 /* Clipped because z > 1.0 */
2186 color = getPixelColor(device, 28, 238);
2187 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2188 color = getPixelColor(device, 28, 241);
2189 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2191 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193 else
2195 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2198 /* Not clipped, > z buffer clear value(0.75) */
2199 color = getPixelColor(device, 31, 238);
2200 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2201 color = getPixelColor(device, 31, 241);
2202 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2203 color = getPixelColor(device, 100, 238);
2204 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2205 color = getPixelColor(device, 100, 241);
2206 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2208 /* Not clipped, < z buffer clear value */
2209 color = getPixelColor(device, 104, 238);
2210 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2211 color = getPixelColor(device, 104, 241);
2212 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2213 color = getPixelColor(device, 318, 238);
2214 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2215 color = getPixelColor(device, 318, 241);
2216 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2218 /* Clipped because z < 0.0 */
2219 color = getPixelColor(device, 321, 238);
2220 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2221 color = getPixelColor(device, 321, 241);
2222 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2224 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2226 else
2228 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2231 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2232 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2234 /* Test the shader path */
2235 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2236 skip("Vertex shaders not supported\n");
2237 goto out;
2239 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2240 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2241 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2242 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2244 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2246 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2247 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2248 IDirect3DDevice9_SetVertexShader(device, shader);
2249 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2251 hr = IDirect3DDevice9_BeginScene(device);
2252 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2253 if(hr == D3D_OK)
2255 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2256 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2257 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2259 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2261 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2262 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2263 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2264 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2266 hr = IDirect3DDevice9_EndScene(device);
2267 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2270 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2271 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2272 IDirect3DDevice9_SetVertexShader(device, NULL);
2273 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2275 IDirect3DVertexDeclaration9_Release(decl);
2276 IDirect3DVertexShader9_Release(shader);
2278 /* Z < 1.0 */
2279 color = getPixelColor(device, 28, 238);
2280 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2282 /* 1.0 < z < 0.75 */
2283 color = getPixelColor(device, 31, 238);
2284 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2285 color = getPixelColor(device, 100, 238);
2286 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2288 /* 0.75 < z < 0.0 */
2289 color = getPixelColor(device, 104, 238);
2290 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2291 color = getPixelColor(device, 318, 238);
2292 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2294 /* 0.0 < z */
2295 color = getPixelColor(device, 321, 238);
2296 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2298 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2299 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2301 out:
2302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2305 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2310 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2312 D3DSURFACE_DESC desc;
2313 D3DLOCKED_RECT l;
2314 HRESULT hr;
2315 unsigned int x, y;
2316 DWORD *mem;
2318 memset(&desc, 0, sizeof(desc));
2319 memset(&l, 0, sizeof(l));
2320 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2321 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2322 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2323 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2324 if(FAILED(hr)) return;
2326 for(y = 0; y < desc.Height; y++)
2328 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2329 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2331 mem[x] = color;
2334 hr = IDirect3DSurface9_UnlockRect(surface);
2335 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2338 /* This tests a variety of possible StretchRect() situations */
2339 static void stretchrect_test(IDirect3DDevice9 *device)
2341 HRESULT hr;
2342 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2343 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2344 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2345 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2346 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2347 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2348 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2349 IDirect3DSurface9 *orig_rt = NULL;
2350 IDirect3DSurface9 *backbuffer = NULL;
2351 DWORD color;
2353 RECT src_rect64 = {0, 0, 64, 64};
2354 RECT src_rect64_flipy = {0, 64, 64, 0};
2355 RECT dst_rect64 = {0, 0, 64, 64};
2356 RECT dst_rect64_flipy = {0, 64, 64, 0};
2358 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2359 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2360 if(!orig_rt) {
2361 goto out;
2364 /* Create our temporary surfaces in system memory */
2365 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2366 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2367 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2368 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2370 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2371 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2372 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2373 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2374 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2375 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2376 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2378 /* Create render target surfaces */
2379 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2380 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2381 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2382 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2383 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2384 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2385 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2386 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2388 /* Create render target textures */
2389 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2390 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2391 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2392 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2393 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2394 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2395 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2396 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2397 if (tex_rt32) {
2398 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2399 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2401 if (tex_rt64) {
2402 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2403 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2405 if (tex_rt_dest64) {
2406 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2407 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2409 if (tex_rt_dest64) {
2410 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2411 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2414 /* Create regular textures in D3DPOOL_DEFAULT */
2415 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2416 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2417 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2418 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2419 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2420 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2421 if (tex32) {
2422 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2423 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2425 if (tex64) {
2426 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2427 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2429 if (tex_dest64) {
2430 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2431 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2434 /*********************************************************************
2435 * Tests for when the source parameter is an offscreen plain surface *
2436 *********************************************************************/
2438 /* Fill the offscreen 64x64 surface with green */
2439 if (surf_offscreen64)
2440 fill_surface(surf_offscreen64, 0xff00ff00);
2442 /* offscreenplain ==> offscreenplain, same size */
2443 if(surf_offscreen64 && surf_offscreen_dest64) {
2444 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2445 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2447 if (hr == D3D_OK) {
2448 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2449 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2452 /* Blit without scaling */
2453 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2454 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2456 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2457 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2458 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2461 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2462 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2465 /* offscreenplain ==> rendertarget texture, same size */
2466 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2467 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2468 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2470 /* We can't lock rendertarget textures, so copy to our temp surface first */
2471 if (hr == D3D_OK) {
2472 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2473 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2476 if (hr == D3D_OK) {
2477 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2478 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2481 /* Blit without scaling */
2482 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2483 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2485 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2486 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2487 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2489 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2490 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2491 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2494 /* offscreenplain ==> rendertarget surface, same size */
2495 if(surf_offscreen64 && surf_rt_dest64) {
2496 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2497 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2499 if (hr == D3D_OK) {
2500 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2501 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2504 /* Blit without scaling */
2505 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2506 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2508 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2509 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2510 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2512 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2513 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2514 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2517 /* offscreenplain ==> texture, same size (should fail) */
2518 if(surf_offscreen64 && surf_tex_dest64) {
2519 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2520 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2523 /* Fill the smaller offscreen surface with red */
2524 fill_surface(surf_offscreen32, 0xffff0000);
2526 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2527 if(surf_offscreen32 && surf_offscreen64) {
2528 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2529 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2532 /* offscreenplain ==> rendertarget texture, scaling */
2533 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2534 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2535 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2537 /* We can't lock rendertarget textures, so copy to our temp surface first */
2538 if (hr == D3D_OK) {
2539 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2540 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2543 if (hr == D3D_OK) {
2544 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2545 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2549 /* offscreenplain ==> rendertarget surface, scaling */
2550 if(surf_offscreen32 && surf_rt_dest64) {
2551 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2552 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2554 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2555 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2558 /* offscreenplain ==> texture, scaling (should fail) */
2559 if(surf_offscreen32 && surf_tex_dest64) {
2560 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2561 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2564 /************************************************************
2565 * Tests for when the source parameter is a regular texture *
2566 ************************************************************/
2568 /* Fill the surface of the regular texture with blue */
2569 if (surf_tex64 && surf_temp64) {
2570 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2571 fill_surface(surf_temp64, 0xff0000ff);
2572 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2573 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2576 /* texture ==> offscreenplain, same size */
2577 if(surf_tex64 && surf_offscreen64) {
2578 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2579 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2582 /* texture ==> rendertarget texture, same size */
2583 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2584 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2585 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2587 /* We can't lock rendertarget textures, so copy to our temp surface first */
2588 if (hr == D3D_OK) {
2589 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2590 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2593 if (hr == D3D_OK) {
2594 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2595 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2598 /* Blit without scaling */
2599 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2600 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2602 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2603 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2604 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2606 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2607 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2608 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2611 /* texture ==> rendertarget surface, same size */
2612 if(surf_tex64 && surf_rt_dest64) {
2613 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2614 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2616 if (hr == D3D_OK) {
2617 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2618 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2621 /* Blit without scaling */
2622 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2623 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2626 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2627 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2629 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2630 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2631 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2634 /* texture ==> texture, same size (should fail) */
2635 if(surf_tex64 && surf_tex_dest64) {
2636 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2637 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2640 /* Fill the surface of the smaller regular texture with red */
2641 if (surf_tex32 && surf_temp32) {
2642 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2643 fill_surface(surf_temp32, 0xffff0000);
2644 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2645 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2648 /* texture ==> offscreenplain, scaling (should fail) */
2649 if(surf_tex32 && surf_offscreen64) {
2650 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2651 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2654 /* texture ==> rendertarget texture, scaling */
2655 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2656 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2657 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2659 /* We can't lock rendertarget textures, so copy to our temp surface first */
2660 if (hr == D3D_OK) {
2661 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2662 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2665 if (hr == D3D_OK) {
2666 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2667 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2671 /* texture ==> rendertarget surface, scaling */
2672 if(surf_tex32 && surf_rt_dest64) {
2673 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2674 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2676 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2677 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2680 /* texture ==> texture, scaling (should fail) */
2681 if(surf_tex32 && surf_tex_dest64) {
2682 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2683 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2686 /*****************************************************************
2687 * Tests for when the source parameter is a rendertarget texture *
2688 *****************************************************************/
2690 /* Fill the surface of the rendertarget texture with white */
2691 if (surf_tex_rt64 && surf_temp64) {
2692 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2693 fill_surface(surf_temp64, 0xffffffff);
2694 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2695 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2698 /* rendertarget texture ==> offscreenplain, same size */
2699 if(surf_tex_rt64 && surf_offscreen64) {
2700 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2701 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2704 /* rendertarget texture ==> rendertarget texture, same size */
2705 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2706 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2707 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2709 /* We can't lock rendertarget textures, so copy to our temp surface first */
2710 if (hr == D3D_OK) {
2711 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2712 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2715 if (hr == D3D_OK) {
2716 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2717 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2720 /* Blit without scaling */
2721 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2722 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2724 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2725 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2726 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2728 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2729 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2730 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2733 /* rendertarget texture ==> rendertarget surface, same size */
2734 if(surf_tex_rt64 && surf_rt_dest64) {
2735 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2736 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2738 if (hr == D3D_OK) {
2739 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2740 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2743 /* Blit without scaling */
2744 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2745 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2747 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2748 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2749 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2751 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2752 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2753 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2756 /* rendertarget texture ==> texture, same size (should fail) */
2757 if(surf_tex_rt64 && surf_tex_dest64) {
2758 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2759 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2762 /* Fill the surface of the smaller rendertarget texture with red */
2763 if (surf_tex_rt32 && surf_temp32) {
2764 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2765 fill_surface(surf_temp32, 0xffff0000);
2766 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2767 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2770 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2771 if(surf_tex_rt32 && surf_offscreen64) {
2772 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2773 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2776 /* rendertarget texture ==> rendertarget texture, scaling */
2777 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2778 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2779 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2781 /* We can't lock rendertarget textures, so copy to our temp surface first */
2782 if (hr == D3D_OK) {
2783 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2784 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2787 if (hr == D3D_OK) {
2788 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2789 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2793 /* rendertarget texture ==> rendertarget surface, scaling */
2794 if(surf_tex_rt32 && surf_rt_dest64) {
2795 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2796 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2798 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2799 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2802 /* rendertarget texture ==> texture, scaling (should fail) */
2803 if(surf_tex_rt32 && surf_tex_dest64) {
2804 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2805 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2808 /*****************************************************************
2809 * Tests for when the source parameter is a rendertarget surface *
2810 *****************************************************************/
2812 /* Fill the surface of the rendertarget surface with black */
2813 if (surf_rt64)
2814 fill_surface(surf_rt64, 0xff000000);
2816 /* rendertarget texture ==> offscreenplain, same size */
2817 if(surf_rt64 && surf_offscreen64) {
2818 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2819 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2822 /* rendertarget surface ==> rendertarget texture, same size */
2823 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2824 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2825 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2827 /* We can't lock rendertarget textures, so copy to our temp surface first */
2828 if (hr == D3D_OK) {
2829 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2830 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2833 if (hr == D3D_OK) {
2834 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2835 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2838 /* Blit without scaling */
2839 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2840 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2842 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2843 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2844 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2846 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2847 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2848 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2851 /* rendertarget surface ==> rendertarget surface, same size */
2852 if(surf_rt64 && surf_rt_dest64) {
2853 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2854 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856 if (hr == D3D_OK) {
2857 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2858 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2861 /* Blit without scaling */
2862 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2863 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2865 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2866 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2867 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2869 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2870 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2871 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2874 /* rendertarget surface ==> texture, same size (should fail) */
2875 if(surf_rt64 && surf_tex_dest64) {
2876 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2877 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2880 /* Fill the surface of the smaller rendertarget texture with red */
2881 if (surf_rt32)
2882 fill_surface(surf_rt32, 0xffff0000);
2884 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2885 if(surf_rt32 && surf_offscreen64) {
2886 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2887 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2890 /* rendertarget surface ==> rendertarget texture, scaling */
2891 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2892 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2893 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2895 /* We can't lock rendertarget textures, so copy to our temp surface first */
2896 if (hr == D3D_OK) {
2897 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2898 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2901 if (hr == D3D_OK) {
2902 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2903 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2907 /* rendertarget surface ==> rendertarget surface, scaling */
2908 if(surf_rt32 && surf_rt_dest64) {
2909 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2910 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2912 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2913 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2916 /* rendertarget surface ==> texture, scaling (should fail) */
2917 if(surf_rt32 && surf_tex_dest64) {
2918 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2919 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2922 /* backbuffer ==> surface tests (no scaling) */
2923 if(backbuffer && surf_tex_rt_dest640_480)
2925 RECT src_rect = {0, 0, 640, 480};
2926 RECT src_rect_flipy = {0, 480, 640, 0};
2927 RECT dst_rect = {0, 0, 640, 480};
2928 RECT dst_rect_flipy = {0, 480, 640, 0};
2930 /* Blit with NULL rectangles */
2931 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2932 ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2934 /* Blit without scaling */
2935 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2936 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2938 /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2939 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2940 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2942 /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2943 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2944 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2947 /* TODO: Test format conversions */
2950 out:
2951 /* Clean up */
2952 if (backbuffer)
2953 IDirect3DSurface9_Release(backbuffer);
2954 if (surf_rt32)
2955 IDirect3DSurface9_Release(surf_rt32);
2956 if (surf_rt64)
2957 IDirect3DSurface9_Release(surf_rt64);
2958 if (surf_rt_dest64)
2959 IDirect3DSurface9_Release(surf_rt_dest64);
2960 if (surf_temp32)
2961 IDirect3DSurface9_Release(surf_temp32);
2962 if (surf_temp64)
2963 IDirect3DSurface9_Release(surf_temp64);
2964 if (surf_offscreen32)
2965 IDirect3DSurface9_Release(surf_offscreen32);
2966 if (surf_offscreen64)
2967 IDirect3DSurface9_Release(surf_offscreen64);
2968 if (surf_offscreen_dest64)
2969 IDirect3DSurface9_Release(surf_offscreen_dest64);
2971 if (tex_rt32) {
2972 if (surf_tex_rt32)
2973 IDirect3DSurface9_Release(surf_tex_rt32);
2974 IDirect3DTexture9_Release(tex_rt32);
2976 if (tex_rt64) {
2977 if (surf_tex_rt64)
2978 IDirect3DSurface9_Release(surf_tex_rt64);
2979 IDirect3DTexture9_Release(tex_rt64);
2981 if (tex_rt_dest64) {
2982 if (surf_tex_rt_dest64)
2983 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2984 IDirect3DTexture9_Release(tex_rt_dest64);
2986 if (tex_rt_dest640_480) {
2987 if (surf_tex_rt_dest640_480)
2988 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2989 IDirect3DTexture9_Release(tex_rt_dest640_480);
2991 if (tex32) {
2992 if (surf_tex32)
2993 IDirect3DSurface9_Release(surf_tex32);
2994 IDirect3DTexture9_Release(tex32);
2996 if (tex64) {
2997 if (surf_tex64)
2998 IDirect3DSurface9_Release(surf_tex64);
2999 IDirect3DTexture9_Release(tex64);
3001 if (tex_dest64) {
3002 if (surf_tex_dest64)
3003 IDirect3DSurface9_Release(surf_tex_dest64);
3004 IDirect3DTexture9_Release(tex_dest64);
3007 if (orig_rt) {
3008 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
3009 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
3010 IDirect3DSurface9_Release(orig_rt);
3014 static void maxmip_test(IDirect3DDevice9 *device)
3016 IDirect3DTexture9 *texture = NULL;
3017 IDirect3DSurface9 *surface = NULL;
3018 HRESULT hr;
3019 DWORD color;
3020 static const struct
3022 struct
3024 float x, y, z;
3025 float s, t;
3027 v[4];
3029 quads[] =
3032 {-1.0, -1.0, 0.0, 0.0, 0.0},
3033 {-1.0, 0.0, 0.0, 0.0, 1.0},
3034 { 0.0, -1.0, 0.0, 1.0, 0.0},
3035 { 0.0, 0.0, 0.0, 1.0, 1.0},
3038 { 0.0, -1.0, 0.0, 0.0, 0.0},
3039 { 0.0, 0.0, 0.0, 0.0, 1.0},
3040 { 1.0, -1.0, 0.0, 1.0, 0.0},
3041 { 1.0, 0.0, 0.0, 1.0, 1.0},
3044 { 0.0, 0.0, 0.0, 0.0, 0.0},
3045 { 0.0, 1.0, 0.0, 0.0, 1.0},
3046 { 1.0, 0.0, 0.0, 1.0, 0.0},
3047 { 1.0, 1.0, 0.0, 1.0, 1.0},
3050 {-1.0, 0.0, 0.0, 0.0, 0.0},
3051 {-1.0, 1.0, 0.0, 0.0, 1.0},
3052 { 0.0, 0.0, 0.0, 1.0, 0.0},
3053 { 0.0, 1.0, 0.0, 1.0, 1.0},
3057 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3058 &texture, NULL);
3059 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3060 if(!texture)
3062 skip("Failed to create test texture\n");
3063 return;
3066 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3067 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3068 fill_surface(surface, 0xffff0000);
3069 IDirect3DSurface9_Release(surface);
3070 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3071 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3072 fill_surface(surface, 0xff00ff00);
3073 IDirect3DSurface9_Release(surface);
3074 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3075 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3076 fill_surface(surface, 0xff0000ff);
3077 IDirect3DSurface9_Release(surface);
3079 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3080 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3082 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3084 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3085 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3087 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3088 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3090 hr = IDirect3DDevice9_BeginScene(device);
3091 if(SUCCEEDED(hr))
3093 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3094 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3096 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3098 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3099 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3101 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3103 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3104 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3108 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3109 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3110 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3111 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3112 hr = IDirect3DDevice9_EndScene(device);
3113 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3116 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3117 color = getPixelColor(device, 160, 360);
3118 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3119 color = getPixelColor(device, 480, 360);
3120 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3121 color = getPixelColor(device, 480, 120);
3122 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3123 color = getPixelColor(device, 160, 120);
3124 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3125 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3126 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3128 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3129 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3134 hr = IDirect3DDevice9_BeginScene(device);
3135 if(SUCCEEDED(hr))
3137 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3138 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3140 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3142 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3143 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3145 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3147 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3148 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3150 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3152 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3153 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3155 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3156 hr = IDirect3DDevice9_EndScene(device);
3157 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3160 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3161 * level 3 (> levels in texture) samples from the highest level in the
3162 * texture (level 2). */
3163 color = getPixelColor(device, 160, 360);
3164 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3165 color = getPixelColor(device, 480, 360);
3166 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3167 color = getPixelColor(device, 480, 120);
3168 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3169 color = getPixelColor(device, 160, 120);
3170 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3171 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3172 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3175 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3177 hr = IDirect3DDevice9_BeginScene(device);
3178 if(SUCCEEDED(hr))
3180 DWORD ret;
3182 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3183 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3184 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3185 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3186 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3187 ret = IDirect3DTexture9_SetLOD(texture, 1);
3188 ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3190 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3192 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3193 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3194 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3195 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3196 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3197 ret = IDirect3DTexture9_SetLOD(texture, 2);
3198 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3200 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3202 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3203 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3204 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3205 ret = IDirect3DTexture9_SetLOD(texture, 1);
3206 ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3208 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3210 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3212 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3213 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3214 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3215 ret = IDirect3DTexture9_SetLOD(texture, 1);
3216 ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3218 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3219 hr = IDirect3DDevice9_EndScene(device);
3220 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3223 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3224 * level 3 (> levels in texture) samples from the highest level in the
3225 * texture (level 2). */
3226 color = getPixelColor(device, 160, 360);
3227 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3228 color = getPixelColor(device, 480, 360);
3229 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3230 color = getPixelColor(device, 480, 120);
3231 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3232 color = getPixelColor(device, 160, 120);
3233 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3235 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3236 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3238 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3239 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3241 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3243 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3244 IDirect3DTexture9_Release(texture);
3247 static void release_buffer_test(IDirect3DDevice9 *device)
3249 IDirect3DVertexBuffer9 *vb = NULL;
3250 IDirect3DIndexBuffer9 *ib = NULL;
3251 HRESULT hr;
3252 BYTE *data;
3253 LONG ref;
3255 static const struct vertex quad[] = {
3256 {-1.0, -1.0, 0.1, 0xffff0000},
3257 {-1.0, 1.0, 0.1, 0xffff0000},
3258 { 1.0, 1.0, 0.1, 0xffff0000},
3260 {-1.0, -1.0, 0.1, 0xff00ff00},
3261 {-1.0, 1.0, 0.1, 0xff00ff00},
3262 { 1.0, 1.0, 0.1, 0xff00ff00}
3264 short indices[] = {3, 4, 5};
3266 /* Index and vertex buffers should always be creatable */
3267 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3268 D3DPOOL_MANAGED, &vb, NULL);
3269 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3270 if(!vb) {
3271 skip("Failed to create a vertex buffer\n");
3272 return;
3274 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3275 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3276 if(!ib) {
3277 skip("Failed to create an index buffer\n");
3278 return;
3281 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3282 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3283 memcpy(data, quad, sizeof(quad));
3284 hr = IDirect3DVertexBuffer9_Unlock(vb);
3285 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3287 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3288 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3289 memcpy(data, indices, sizeof(indices));
3290 hr = IDirect3DIndexBuffer9_Unlock(ib);
3291 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3293 hr = IDirect3DDevice9_SetIndices(device, ib);
3294 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3295 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3296 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3297 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3298 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3300 /* Now destroy the bound index buffer and draw again */
3301 ref = IDirect3DIndexBuffer9_Release(ib);
3302 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3304 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3305 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3307 hr = IDirect3DDevice9_BeginScene(device);
3308 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3309 if(SUCCEEDED(hr))
3311 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3312 * making assumptions about the indices or vertices
3314 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3315 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3316 hr = IDirect3DDevice9_EndScene(device);
3317 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3320 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3321 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3323 hr = IDirect3DDevice9_SetIndices(device, NULL);
3324 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3325 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3326 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3328 /* Index buffer was already destroyed as part of the test */
3329 IDirect3DVertexBuffer9_Release(vb);
3332 static void float_texture_test(IDirect3DDevice9 *device)
3334 IDirect3D9 *d3d = NULL;
3335 HRESULT hr;
3336 IDirect3DTexture9 *texture = NULL;
3337 D3DLOCKED_RECT lr;
3338 float *data;
3339 DWORD color;
3340 float quad[] = {
3341 -1.0, -1.0, 0.1, 0.0, 0.0,
3342 -1.0, 1.0, 0.1, 0.0, 1.0,
3343 1.0, -1.0, 0.1, 1.0, 0.0,
3344 1.0, 1.0, 0.1, 1.0, 1.0,
3347 memset(&lr, 0, sizeof(lr));
3348 IDirect3DDevice9_GetDirect3D(device, &d3d);
3349 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3350 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3351 skip("D3DFMT_R32F textures not supported\n");
3352 goto out;
3355 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3356 D3DPOOL_MANAGED, &texture, NULL);
3357 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3358 if(!texture) {
3359 skip("Failed to create R32F texture\n");
3360 goto out;
3363 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3364 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3365 data = lr.pBits;
3366 *data = 0.0;
3367 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3368 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3370 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3371 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3373 hr = IDirect3DDevice9_BeginScene(device);
3374 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3375 if(SUCCEEDED(hr))
3377 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3378 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3381 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3383 hr = IDirect3DDevice9_EndScene(device);
3384 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3386 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3387 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3389 color = getPixelColor(device, 240, 320);
3390 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3393 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3395 out:
3396 if(texture) IDirect3DTexture9_Release(texture);
3397 IDirect3D9_Release(d3d);
3400 static void g16r16_texture_test(IDirect3DDevice9 *device)
3402 IDirect3D9 *d3d = NULL;
3403 HRESULT hr;
3404 IDirect3DTexture9 *texture = NULL;
3405 D3DLOCKED_RECT lr;
3406 DWORD *data;
3407 DWORD color;
3408 float quad[] = {
3409 -1.0, -1.0, 0.1, 0.0, 0.0,
3410 -1.0, 1.0, 0.1, 0.0, 1.0,
3411 1.0, -1.0, 0.1, 1.0, 0.0,
3412 1.0, 1.0, 0.1, 1.0, 1.0,
3415 memset(&lr, 0, sizeof(lr));
3416 IDirect3DDevice9_GetDirect3D(device, &d3d);
3417 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3418 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3419 skip("D3DFMT_G16R16 textures not supported\n");
3420 goto out;
3423 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3424 D3DPOOL_MANAGED, &texture, NULL);
3425 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3426 if(!texture) {
3427 skip("Failed to create D3DFMT_G16R16 texture\n");
3428 goto out;
3431 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3432 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3433 data = lr.pBits;
3434 *data = 0x0f00f000;
3435 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3436 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3438 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3439 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3441 hr = IDirect3DDevice9_BeginScene(device);
3442 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3443 if(SUCCEEDED(hr))
3445 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3446 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3448 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3449 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3451 hr = IDirect3DDevice9_EndScene(device);
3452 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3454 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3455 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3457 color = getPixelColor(device, 240, 320);
3458 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3459 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3461 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3462 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3464 out:
3465 if(texture) IDirect3DTexture9_Release(texture);
3466 IDirect3D9_Release(d3d);
3469 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3471 HRESULT hr;
3472 IDirect3D9 *d3d;
3473 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3474 D3DCAPS9 caps;
3475 IDirect3DTexture9 *texture = NULL;
3476 IDirect3DVolumeTexture9 *volume = NULL;
3477 unsigned int x, y, z;
3478 D3DLOCKED_RECT lr;
3479 D3DLOCKED_BOX lb;
3480 DWORD color;
3481 UINT w, h;
3482 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3483 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3484 0.0, 1.0, 0.0, 0.0,
3485 0.0, 0.0, 1.0, 0.0,
3486 0.0, 0.0, 0.0, 1.0};
3487 static const D3DVERTEXELEMENT9 decl_elements[] = {
3488 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3489 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3490 D3DDECL_END()
3492 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3493 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3494 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3495 D3DDECL_END()
3497 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3498 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3499 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3500 D3DDECL_END()
3502 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3503 0x00, 0xff, 0x00, 0x00,
3504 0x00, 0x00, 0x00, 0x00,
3505 0x00, 0x00, 0x00, 0x00};
3507 memset(&lr, 0, sizeof(lr));
3508 memset(&lb, 0, sizeof(lb));
3509 IDirect3DDevice9_GetDirect3D(device, &d3d);
3510 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3511 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3512 fmt = D3DFMT_A16B16G16R16;
3514 IDirect3D9_Release(d3d);
3516 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3517 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3518 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3519 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3520 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3521 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3522 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3523 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3524 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3525 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3526 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3527 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3528 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3529 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3530 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3531 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3532 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3533 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3534 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3535 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3537 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3539 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3541 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3542 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3543 w = min(1024, caps.MaxTextureWidth);
3544 h = min(1024, caps.MaxTextureHeight);
3545 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3546 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3547 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3548 if(!texture) {
3549 skip("Failed to create the test texture\n");
3550 return;
3553 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3554 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3555 * 1.0 in red and green for the x and y coords
3557 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3558 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3559 for(y = 0; y < h; y++) {
3560 for(x = 0; x < w; x++) {
3561 double r_f = (double) y / (double) h;
3562 double g_f = (double) x / (double) w;
3563 if(fmt == D3DFMT_A16B16G16R16) {
3564 unsigned short r, g;
3565 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3566 r = (unsigned short) (r_f * 65536.0);
3567 g = (unsigned short) (g_f * 65536.0);
3568 dst[0] = r;
3569 dst[1] = g;
3570 dst[2] = 0;
3571 dst[3] = 65535;
3572 } else {
3573 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3574 unsigned char r = (unsigned char) (r_f * 255.0);
3575 unsigned char g = (unsigned char) (g_f * 255.0);
3576 dst[0] = 0;
3577 dst[1] = g;
3578 dst[2] = r;
3579 dst[3] = 255;
3583 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3584 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3585 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3586 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3588 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3589 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3590 hr = IDirect3DDevice9_BeginScene(device);
3591 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3592 if(SUCCEEDED(hr))
3594 float quad1[] = {
3595 -1.0, -1.0, 0.1, 1.0, 1.0,
3596 -1.0, 0.0, 0.1, 1.0, 1.0,
3597 0.0, -1.0, 0.1, 1.0, 1.0,
3598 0.0, 0.0, 0.1, 1.0, 1.0,
3600 float quad2[] = {
3601 -1.0, 0.0, 0.1, 1.0, 1.0,
3602 -1.0, 1.0, 0.1, 1.0, 1.0,
3603 0.0, 0.0, 0.1, 1.0, 1.0,
3604 0.0, 1.0, 0.1, 1.0, 1.0,
3606 float quad3[] = {
3607 0.0, 0.0, 0.1, 0.5, 0.5,
3608 0.0, 1.0, 0.1, 0.5, 0.5,
3609 1.0, 0.0, 0.1, 0.5, 0.5,
3610 1.0, 1.0, 0.1, 0.5, 0.5,
3612 float quad4[] = {
3613 320, 480, 0.1, 1.0, 0.0, 1.0,
3614 320, 240, 0.1, 1.0, 0.0, 1.0,
3615 640, 480, 0.1, 1.0, 0.0, 1.0,
3616 640, 240, 0.1, 1.0, 0.0, 1.0,
3618 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3619 0.0, 0.0, 0.0, 0.0,
3620 0.0, 0.0, 0.0, 0.0,
3621 0.0, 0.0, 0.0, 0.0};
3623 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3624 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3625 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3627 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3629 /* What happens with transforms enabled? */
3630 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3631 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3633 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3635 /* What happens if 4 coords are used, but only 2 given ?*/
3636 mat[8] = 1.0;
3637 mat[13] = 1.0;
3638 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3639 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3640 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3641 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3643 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3645 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3646 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3647 * due to the coords in the vertices. (turns out red, indeed)
3649 memset(mat, 0, sizeof(mat));
3650 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3651 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3652 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3653 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3654 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3657 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3659 hr = IDirect3DDevice9_EndScene(device);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3662 color = getPixelColor(device, 160, 360);
3663 ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3664 color = getPixelColor(device, 160, 120);
3665 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3666 color = getPixelColor(device, 480, 120);
3667 ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3668 color = getPixelColor(device, 480, 360);
3669 ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3670 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3671 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3676 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3677 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3678 hr = IDirect3DDevice9_BeginScene(device);
3679 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3680 if(SUCCEEDED(hr))
3682 float quad1[] = {
3683 -1.0, -1.0, 0.1, 0.8, 0.2,
3684 -1.0, 0.0, 0.1, 0.8, 0.2,
3685 0.0, -1.0, 0.1, 0.8, 0.2,
3686 0.0, 0.0, 0.1, 0.8, 0.2,
3688 float quad2[] = {
3689 -1.0, 0.0, 0.1, 0.5, 1.0,
3690 -1.0, 1.0, 0.1, 0.5, 1.0,
3691 0.0, 0.0, 0.1, 0.5, 1.0,
3692 0.0, 1.0, 0.1, 0.5, 1.0,
3694 float quad3[] = {
3695 0.0, 0.0, 0.1, 0.5, 1.0,
3696 0.0, 1.0, 0.1, 0.5, 1.0,
3697 1.0, 0.0, 0.1, 0.5, 1.0,
3698 1.0, 1.0, 0.1, 0.5, 1.0,
3700 float quad4[] = {
3701 0.0, -1.0, 0.1, 0.8, 0.2,
3702 0.0, 0.0, 0.1, 0.8, 0.2,
3703 1.0, -1.0, 0.1, 0.8, 0.2,
3704 1.0, 0.0, 0.1, 0.8, 0.2,
3706 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3707 0.0, 0.0, 0.0, 0.0,
3708 0.0, 1.0, 0.0, 0.0,
3709 0.0, 0.0, 0.0, 0.0};
3711 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3713 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3714 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3715 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3716 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3719 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3721 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3722 * it behaves like COUNT2 because normal textures require 2 coords
3724 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3725 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3727 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3729 /* Just to be sure, the same as quad2 above */
3730 memset(mat, 0, sizeof(mat));
3731 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3732 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3733 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3734 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3736 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3738 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3739 * used? And what happens to the first?
3741 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3742 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3744 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3746 hr = IDirect3DDevice9_EndScene(device);
3747 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3749 color = getPixelColor(device, 160, 360);
3750 ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3751 color = getPixelColor(device, 160, 120);
3752 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3753 color = getPixelColor(device, 480, 120);
3754 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3755 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3756 color = getPixelColor(device, 480, 360);
3757 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3758 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3759 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3762 IDirect3DTexture9_Release(texture);
3764 /* Test projected textures, without any fancy matrices */
3765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3767 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3768 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3769 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3771 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3772 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3774 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3775 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3776 for(x = 0; x < 4; x++) {
3777 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3779 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3780 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3781 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3784 hr = IDirect3DDevice9_BeginScene(device);
3785 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3786 if(SUCCEEDED(hr))
3788 const float proj_quads[] = {
3789 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3790 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3791 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3792 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3793 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3794 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3795 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3796 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3799 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3800 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3802 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3804 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3805 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3807 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3809 hr = IDirect3DDevice9_EndScene(device);
3810 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3813 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3814 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3815 IDirect3DTexture9_Release(texture);
3817 color = getPixelColor(device, 158, 118);
3818 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3819 color = getPixelColor(device, 162, 118);
3820 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3821 color = getPixelColor(device, 158, 122);
3822 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3823 color = getPixelColor(device, 162, 122);
3824 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3826 color = getPixelColor(device, 158, 178);
3827 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3828 color = getPixelColor(device, 162, 178);
3829 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3830 color = getPixelColor(device, 158, 182);
3831 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3832 color = getPixelColor(device, 162, 182);
3833 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3835 color = getPixelColor(device, 318, 118);
3836 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3837 color = getPixelColor(device, 322, 118);
3838 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3839 color = getPixelColor(device, 318, 122);
3840 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3841 color = getPixelColor(device, 322, 122);
3842 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3844 color = getPixelColor(device, 318, 178);
3845 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3846 color = getPixelColor(device, 322, 178);
3847 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3848 color = getPixelColor(device, 318, 182);
3849 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3850 color = getPixelColor(device, 322, 182);
3851 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3853 color = getPixelColor(device, 238, 298);
3854 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3855 color = getPixelColor(device, 242, 298);
3856 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3857 color = getPixelColor(device, 238, 302);
3858 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3859 color = getPixelColor(device, 242, 302);
3860 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3862 color = getPixelColor(device, 238, 388);
3863 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3864 color = getPixelColor(device, 242, 388);
3865 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3866 color = getPixelColor(device, 238, 392);
3867 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3868 color = getPixelColor(device, 242, 392);
3869 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3871 color = getPixelColor(device, 478, 298);
3872 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3873 color = getPixelColor(device, 482, 298);
3874 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3875 color = getPixelColor(device, 478, 302);
3876 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3877 color = getPixelColor(device, 482, 302);
3878 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3880 color = getPixelColor(device, 478, 388);
3881 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3882 color = getPixelColor(device, 482, 388);
3883 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3884 color = getPixelColor(device, 478, 392);
3885 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3886 color = getPixelColor(device, 482, 392);
3887 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3889 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3890 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3893 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3894 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3895 * Thus watch out if sampling from texels between 0 and 1.
3897 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3898 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3899 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3900 if(!volume) {
3901 skip("Failed to create a volume texture\n");
3902 goto out;
3905 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3906 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3907 for(z = 0; z < 32; z++) {
3908 for(y = 0; y < 32; y++) {
3909 for(x = 0; x < 32; x++) {
3910 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3911 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3912 float r_f = (float) x / 31.0;
3913 float g_f = (float) y / 31.0;
3914 float b_f = (float) z / 31.0;
3916 if(fmt == D3DFMT_A16B16G16R16) {
3917 unsigned short *mem_s = mem;
3918 mem_s[0] = r_f * 65535.0;
3919 mem_s[1] = g_f * 65535.0;
3920 mem_s[2] = b_f * 65535.0;
3921 mem_s[3] = 65535;
3922 } else {
3923 unsigned char *mem_c = mem;
3924 mem_c[0] = b_f * 255.0;
3925 mem_c[1] = g_f * 255.0;
3926 mem_c[2] = r_f * 255.0;
3927 mem_c[3] = 255;
3932 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3933 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3935 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3936 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3938 hr = IDirect3DDevice9_BeginScene(device);
3939 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3940 if(SUCCEEDED(hr))
3942 float quad1[] = {
3943 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3944 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3945 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3946 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3948 float quad2[] = {
3949 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3950 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3951 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3952 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3954 float quad3[] = {
3955 0.0, 0.0, 0.1, 0.0, 0.0,
3956 0.0, 1.0, 0.1, 0.0, 0.0,
3957 1.0, 0.0, 0.1, 0.0, 0.0,
3958 1.0, 1.0, 0.1, 0.0, 0.0
3960 float quad4[] = {
3961 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3962 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3963 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3964 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3966 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3967 0.0, 0.0, 1.0, 0.0,
3968 0.0, 1.0, 0.0, 0.0,
3969 0.0, 0.0, 0.0, 1.0};
3970 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3971 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3973 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3974 * values
3976 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3978 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3979 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3980 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3981 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3983 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3984 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3985 * otherwise the w will be missing(blue).
3986 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3987 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3989 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3990 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3992 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3994 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3995 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3996 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3997 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3998 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3999 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4000 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4002 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4004 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
4005 * disable. ATI extends it up to the amount of values needed for the volume texture
4007 memset(mat, 0, sizeof(mat));
4008 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4009 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4010 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4011 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4012 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4015 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4017 hr = IDirect3DDevice9_EndScene(device);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4021 color = getPixelColor(device, 160, 360);
4022 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4023 color = getPixelColor(device, 160, 120);
4024 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4025 "quad 2 has color %08x, expected 0x00ffff00\n", color);
4026 color = getPixelColor(device, 480, 120);
4027 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4028 color = getPixelColor(device, 480, 360);
4029 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4031 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4035 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4036 hr = IDirect3DDevice9_BeginScene(device);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4038 if(SUCCEEDED(hr))
4040 float quad1[] = {
4041 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4042 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
4043 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
4044 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
4046 float quad2[] = {
4047 -1.0, 0.0, 0.1,
4048 -1.0, 1.0, 0.1,
4049 0.0, 0.0, 0.1,
4050 0.0, 1.0, 0.1,
4052 float quad3[] = {
4053 0.0, 0.0, 0.1, 1.0,
4054 0.0, 1.0, 0.1, 1.0,
4055 1.0, 0.0, 0.1, 1.0,
4056 1.0, 1.0, 0.1, 1.0
4058 float mat[16] = {0.0, 0.0, 0.0, 0.0,
4059 0.0, 0.0, 0.0, 0.0,
4060 0.0, 0.0, 0.0, 0.0,
4061 0.0, 1.0, 0.0, 0.0};
4062 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4063 1.0, 0.0, 0.0, 0.0,
4064 0.0, 1.0, 0.0, 0.0,
4065 0.0, 0.0, 1.0, 0.0};
4066 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4067 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4069 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4070 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4071 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4072 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4073 * 4th *input* coordinate.
4075 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4076 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4077 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4078 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4080 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4082 /* None passed */
4083 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4084 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4085 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4086 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4088 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4090 /* 4 used, 1 passed */
4091 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4092 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4093 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4094 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4096 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4098 hr = IDirect3DDevice9_EndScene(device);
4099 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4101 color = getPixelColor(device, 160, 360);
4102 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4103 color = getPixelColor(device, 160, 120);
4104 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4105 color = getPixelColor(device, 480, 120);
4106 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4107 /* Quad4: unused */
4109 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4110 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4112 IDirect3DVolumeTexture9_Release(volume);
4114 out:
4115 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4116 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4117 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4118 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4119 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4120 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4121 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4122 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4123 IDirect3DVertexDeclaration9_Release(decl);
4124 IDirect3DVertexDeclaration9_Release(decl2);
4125 IDirect3DVertexDeclaration9_Release(decl3);
4128 static void texdepth_test(IDirect3DDevice9 *device)
4130 IDirect3DPixelShader9 *shader;
4131 HRESULT hr;
4132 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
4133 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
4134 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
4135 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4136 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4137 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
4138 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
4139 DWORD shader_code[] = {
4140 0xffff0104, /* ps_1_4 */
4141 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
4142 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
4143 0x0000fffd, /* phase */
4144 0x00000057, 0x800f0005, /* texdepth r5 */
4145 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
4146 0x0000ffff /* end */
4148 DWORD color;
4149 float vertex[] = {
4150 -1.0, -1.0, 0.0,
4151 1.0, -1.0, 1.0,
4152 -1.0, 1.0, 0.0,
4153 1.0, 1.0, 1.0
4156 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4157 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4159 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4160 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4162 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4164 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4166 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4167 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4168 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4170 /* Fill the depth buffer with a gradient */
4171 hr = IDirect3DDevice9_BeginScene(device);
4172 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4173 if(SUCCEEDED(hr))
4175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4176 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4177 hr = IDirect3DDevice9_EndScene(device);
4178 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4181 /* Now perform the actual tests. Same geometry, but with the shader */
4182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4183 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4185 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4186 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4187 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4189 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4190 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4191 hr = IDirect3DDevice9_BeginScene(device);
4192 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4193 if(SUCCEEDED(hr))
4195 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4196 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4198 hr = IDirect3DDevice9_EndScene(device);
4199 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4202 color = getPixelColor(device, 158, 240);
4203 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4204 color = getPixelColor(device, 162, 240);
4205 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4207 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4208 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4210 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4211 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4213 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4214 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4215 hr = IDirect3DDevice9_BeginScene(device);
4216 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4217 if(SUCCEEDED(hr))
4219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4220 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4222 hr = IDirect3DDevice9_EndScene(device);
4223 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4226 color = getPixelColor(device, 318, 240);
4227 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4228 color = getPixelColor(device, 322, 240);
4229 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4231 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4232 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4234 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4235 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4237 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4238 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4239 hr = IDirect3DDevice9_BeginScene(device);
4240 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4241 if(SUCCEEDED(hr))
4243 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4244 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4246 hr = IDirect3DDevice9_EndScene(device);
4247 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4250 color = getPixelColor(device, 1, 240);
4251 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4253 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4254 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4256 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4257 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4259 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4260 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4261 hr = IDirect3DDevice9_BeginScene(device);
4262 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4263 if(SUCCEEDED(hr))
4265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4266 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4268 hr = IDirect3DDevice9_EndScene(device);
4269 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4271 color = getPixelColor(device, 318, 240);
4272 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4273 color = getPixelColor(device, 322, 240);
4274 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4276 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4277 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4280 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4282 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4283 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4284 hr = IDirect3DDevice9_BeginScene(device);
4285 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4286 if(SUCCEEDED(hr))
4288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4289 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4291 hr = IDirect3DDevice9_EndScene(device);
4292 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4295 color = getPixelColor(device, 1, 240);
4296 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4298 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4299 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4301 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4302 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4304 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4305 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4306 hr = IDirect3DDevice9_BeginScene(device);
4307 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4308 if(SUCCEEDED(hr))
4310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4311 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4313 hr = IDirect3DDevice9_EndScene(device);
4314 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4317 color = getPixelColor(device, 638, 240);
4318 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4320 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4321 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4323 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4324 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4326 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4327 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4328 hr = IDirect3DDevice9_BeginScene(device);
4329 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4330 if(SUCCEEDED(hr))
4332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4333 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4335 hr = IDirect3DDevice9_EndScene(device);
4336 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4339 color = getPixelColor(device, 638, 240);
4340 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4342 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4343 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4345 /* Cleanup */
4346 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4347 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4348 IDirect3DPixelShader9_Release(shader);
4350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4353 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4356 static void texkill_test(IDirect3DDevice9 *device)
4358 IDirect3DPixelShader9 *shader;
4359 HRESULT hr;
4360 DWORD color;
4362 const float vertex[] = {
4363 /* bottom top right left */
4364 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
4365 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
4366 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
4367 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
4370 DWORD shader_code_11[] = {
4371 0xffff0101, /* ps_1_1 */
4372 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4373 0x00000041, 0xb00f0000, /* texkill t0 */
4374 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4375 0x0000ffff /* end */
4377 DWORD shader_code_20[] = {
4378 0xffff0200, /* ps_2_0 */
4379 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4380 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4381 0x01000041, 0xb00f0000, /* texkill t0 */
4382 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
4383 0x0000ffff /* end */
4386 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4387 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4388 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4389 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4391 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4392 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4393 hr = IDirect3DDevice9_BeginScene(device);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4395 if(SUCCEEDED(hr))
4397 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4398 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4400 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4401 hr = IDirect3DDevice9_EndScene(device);
4402 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4404 color = getPixelColor(device, 63, 46);
4405 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4406 color = getPixelColor(device, 66, 46);
4407 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4408 color = getPixelColor(device, 63, 49);
4409 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4410 color = getPixelColor(device, 66, 49);
4411 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4413 color = getPixelColor(device, 578, 46);
4414 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4415 color = getPixelColor(device, 575, 46);
4416 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4417 color = getPixelColor(device, 578, 49);
4418 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4419 color = getPixelColor(device, 575, 49);
4420 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4422 color = getPixelColor(device, 63, 430);
4423 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4424 color = getPixelColor(device, 63, 433);
4425 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4426 color = getPixelColor(device, 66, 433);
4427 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4428 color = getPixelColor(device, 66, 430);
4429 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4431 color = getPixelColor(device, 578, 430);
4432 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4433 color = getPixelColor(device, 578, 433);
4434 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4435 color = getPixelColor(device, 575, 433);
4436 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4437 color = getPixelColor(device, 575, 430);
4438 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4440 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4441 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4443 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4444 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4445 IDirect3DPixelShader9_Release(shader);
4447 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4448 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4449 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4450 if(FAILED(hr)) {
4451 skip("Failed to create 2.0 test shader, most likely not supported\n");
4452 return;
4455 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4456 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4457 hr = IDirect3DDevice9_BeginScene(device);
4458 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4459 if(SUCCEEDED(hr))
4461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4462 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4463 hr = IDirect3DDevice9_EndScene(device);
4464 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4467 color = getPixelColor(device, 63, 46);
4468 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4469 color = getPixelColor(device, 66, 46);
4470 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4471 color = getPixelColor(device, 63, 49);
4472 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4473 color = getPixelColor(device, 66, 49);
4474 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4476 color = getPixelColor(device, 578, 46);
4477 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4478 color = getPixelColor(device, 575, 46);
4479 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4480 color = getPixelColor(device, 578, 49);
4481 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4482 color = getPixelColor(device, 575, 49);
4483 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4485 color = getPixelColor(device, 63, 430);
4486 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4487 color = getPixelColor(device, 63, 433);
4488 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4489 color = getPixelColor(device, 66, 433);
4490 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4491 color = getPixelColor(device, 66, 430);
4492 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4494 color = getPixelColor(device, 578, 430);
4495 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4496 color = getPixelColor(device, 578, 433);
4497 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4498 color = getPixelColor(device, 575, 433);
4499 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4500 color = getPixelColor(device, 575, 430);
4501 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4503 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4504 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4506 /* Cleanup */
4507 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4508 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4509 IDirect3DPixelShader9_Release(shader);
4512 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4514 IDirect3D9 *d3d9;
4515 HRESULT hr;
4516 IDirect3DTexture9 *texture;
4517 IDirect3DPixelShader9 *shader;
4518 IDirect3DPixelShader9 *shader2;
4519 D3DLOCKED_RECT lr;
4520 DWORD color;
4521 DWORD shader_code[] = {
4522 0xffff0101, /* ps_1_1 */
4523 0x00000042, 0xb00f0000, /* tex t0 */
4524 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4525 0x0000ffff /* end */
4527 DWORD shader_code2[] = {
4528 0xffff0101, /* ps_1_1 */
4529 0x00000042, 0xb00f0000, /* tex t0 */
4530 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4531 0x0000ffff /* end */
4534 float quad[] = {
4535 -1.0, -1.0, 0.1, 0.5, 0.5,
4536 1.0, -1.0, 0.1, 0.5, 0.5,
4537 -1.0, 1.0, 0.1, 0.5, 0.5,
4538 1.0, 1.0, 0.1, 0.5, 0.5,
4541 memset(&lr, 0, sizeof(lr));
4542 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4543 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4544 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4545 IDirect3D9_Release(d3d9);
4546 if(FAILED(hr)) {
4547 skip("No D3DFMT_X8L8V8U8 support\n");
4548 return;
4551 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4554 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4555 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4556 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4557 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4558 *((DWORD *) lr.pBits) = 0x11ca3141;
4559 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4560 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4562 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4563 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4564 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4565 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4567 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4568 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4569 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4571 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4572 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4574 hr = IDirect3DDevice9_BeginScene(device);
4575 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4576 if(SUCCEEDED(hr))
4578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4579 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4581 hr = IDirect3DDevice9_EndScene(device);
4582 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4584 color = getPixelColor(device, 578, 430);
4585 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4586 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4587 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4588 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4590 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4591 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4592 hr = IDirect3DDevice9_BeginScene(device);
4593 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4594 if(SUCCEEDED(hr))
4596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4597 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4599 hr = IDirect3DDevice9_EndScene(device);
4600 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4602 color = getPixelColor(device, 578, 430);
4603 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4604 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4605 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4607 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4608 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4609 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4610 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4611 IDirect3DPixelShader9_Release(shader);
4612 IDirect3DPixelShader9_Release(shader2);
4613 IDirect3DTexture9_Release(texture);
4616 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4618 HRESULT hr;
4619 IDirect3D9 *d3d;
4620 IDirect3DTexture9 *texture = NULL;
4621 IDirect3DSurface9 *surface;
4622 DWORD color;
4623 const RECT r1 = {256, 256, 512, 512};
4624 const RECT r2 = {512, 256, 768, 512};
4625 const RECT r3 = {256, 512, 512, 768};
4626 const RECT r4 = {512, 512, 768, 768};
4627 unsigned int x, y;
4628 D3DLOCKED_RECT lr;
4629 memset(&lr, 0, sizeof(lr));
4631 IDirect3DDevice9_GetDirect3D(device, &d3d);
4632 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4633 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4634 skip("No autogenmipmap support\n");
4635 IDirect3D9_Release(d3d);
4636 return;
4638 IDirect3D9_Release(d3d);
4640 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4641 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4643 /* Make the mipmap big, so that a smaller mipmap is used
4645 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4646 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4647 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4649 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4650 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4651 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4652 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4653 for(y = 0; y < 1024; y++) {
4654 for(x = 0; x < 1024; x++) {
4655 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4656 POINT pt;
4658 pt.x = x;
4659 pt.y = y;
4660 if(PtInRect(&r1, pt)) {
4661 *dst = 0xffff0000;
4662 } else if(PtInRect(&r2, pt)) {
4663 *dst = 0xff00ff00;
4664 } else if(PtInRect(&r3, pt)) {
4665 *dst = 0xff0000ff;
4666 } else if(PtInRect(&r4, pt)) {
4667 *dst = 0xff000000;
4668 } else {
4669 *dst = 0xffffffff;
4673 hr = IDirect3DSurface9_UnlockRect(surface);
4674 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4675 IDirect3DSurface9_Release(surface);
4677 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4678 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4679 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4680 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4682 hr = IDirect3DDevice9_BeginScene(device);
4683 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4684 if(SUCCEEDED(hr)) {
4685 const float quad[] = {
4686 -0.5, -0.5, 0.1, 0.0, 0.0,
4687 -0.5, 0.5, 0.1, 0.0, 1.0,
4688 0.5, -0.5, 0.1, 1.0, 0.0,
4689 0.5, 0.5, 0.1, 1.0, 1.0
4692 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4693 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4695 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4696 hr = IDirect3DDevice9_EndScene(device);
4697 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4699 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4700 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4701 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4702 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4703 IDirect3DTexture9_Release(texture);
4705 color = getPixelColor(device, 200, 200);
4706 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4707 color = getPixelColor(device, 280, 200);
4708 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4709 color = getPixelColor(device, 360, 200);
4710 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4711 color = getPixelColor(device, 440, 200);
4712 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4713 color = getPixelColor(device, 200, 270);
4714 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4715 color = getPixelColor(device, 280, 270);
4716 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4717 color = getPixelColor(device, 360, 270);
4718 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4719 color = getPixelColor(device, 440, 270);
4720 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4721 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4722 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4725 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4727 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4728 IDirect3DVertexDeclaration9 *decl;
4729 HRESULT hr;
4730 DWORD color;
4731 DWORD shader_code_11[] = {
4732 0xfffe0101, /* vs_1_1 */
4733 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4734 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4735 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4736 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4737 0x0000ffff /* end */
4739 DWORD shader_code_11_2[] = {
4740 0xfffe0101, /* vs_1_1 */
4741 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4742 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4743 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4744 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4745 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4746 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4747 0x0000ffff /* end */
4749 DWORD shader_code_20[] = {
4750 0xfffe0200, /* vs_2_0 */
4751 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4752 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4753 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4754 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4755 0x0000ffff /* end */
4757 DWORD shader_code_20_2[] = {
4758 0xfffe0200, /* vs_2_0 */
4759 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4760 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4761 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4762 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4763 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4764 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4765 0x0000ffff /* end */
4767 static const D3DVERTEXELEMENT9 decl_elements[] = {
4768 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4769 D3DDECL_END()
4771 float quad1[] = {
4772 -1.0, -1.0, 0.1,
4773 0.0, -1.0, 0.1,
4774 -1.0, 0.0, 0.1,
4775 0.0, 0.0, 0.1
4777 float quad2[] = {
4778 0.0, -1.0, 0.1,
4779 1.0, -1.0, 0.1,
4780 0.0, 0.0, 0.1,
4781 1.0, 0.0, 0.1
4783 float quad3[] = {
4784 0.0, 0.0, 0.1,
4785 1.0, 0.0, 0.1,
4786 0.0, 1.0, 0.1,
4787 1.0, 1.0, 0.1
4789 float quad4[] = {
4790 -1.0, 0.0, 0.1,
4791 0.0, 0.0, 0.1,
4792 -1.0, 1.0, 0.1,
4793 0.0, 1.0, 0.1
4795 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4796 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4798 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4799 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4801 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4802 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4803 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4804 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4805 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4806 if(FAILED(hr)) shader_20 = NULL;
4807 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4808 if(FAILED(hr)) shader_20_2 = NULL;
4809 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4810 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4812 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4813 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4814 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4815 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4816 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4817 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4819 hr = IDirect3DDevice9_BeginScene(device);
4820 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4821 if(SUCCEEDED(hr))
4823 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4826 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4828 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4829 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4831 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4833 if(shader_20) {
4834 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4835 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4837 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4840 if(shader_20_2) {
4841 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4843 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4844 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4847 hr = IDirect3DDevice9_EndScene(device);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4851 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4853 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4856 color = getPixelColor(device, 160, 360);
4857 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4858 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4859 color = getPixelColor(device, 480, 360);
4860 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4861 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4862 if(shader_20) {
4863 color = getPixelColor(device, 480, 120);
4864 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4865 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4867 if(shader_20_2) {
4868 color = getPixelColor(device, 160, 120);
4869 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4870 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4872 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4873 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4875 IDirect3DVertexDeclaration9_Release(decl);
4876 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4877 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4878 IDirect3DVertexShader9_Release(shader_11_2);
4879 IDirect3DVertexShader9_Release(shader_11);
4882 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4884 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4885 HRESULT hr;
4886 DWORD color;
4887 DWORD shader_code_11[] = {
4888 0xffff0101, /* ps_1_1 */
4889 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4890 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4891 0x0000ffff /* end */
4893 DWORD shader_code_12[] = {
4894 0xffff0102, /* ps_1_2 */
4895 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4896 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4897 0x0000ffff /* end */
4899 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4900 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4901 * During development of this test, 1.3 shaders were verified too
4903 DWORD shader_code_14[] = {
4904 0xffff0104, /* ps_1_4 */
4905 /* Try to make one constant local. It gets clamped too, although the binary contains
4906 * the bigger numbers
4908 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4909 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4910 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4911 0x0000ffff /* end */
4913 DWORD shader_code_20[] = {
4914 0xffff0200, /* ps_2_0 */
4915 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4916 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4917 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4918 0x0000ffff /* end */
4920 float quad1[] = {
4921 -1.0, -1.0, 0.1,
4922 0.0, -1.0, 0.1,
4923 -1.0, 0.0, 0.1,
4924 0.0, 0.0, 0.1
4926 float quad2[] = {
4927 0.0, -1.0, 0.1,
4928 1.0, -1.0, 0.1,
4929 0.0, 0.0, 0.1,
4930 1.0, 0.0, 0.1
4932 float quad3[] = {
4933 0.0, 0.0, 0.1,
4934 1.0, 0.0, 0.1,
4935 0.0, 1.0, 0.1,
4936 1.0, 1.0, 0.1
4938 float quad4[] = {
4939 -1.0, 0.0, 0.1,
4940 0.0, 0.0, 0.1,
4941 -1.0, 1.0, 0.1,
4942 0.0, 1.0, 0.1
4944 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4945 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4947 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4948 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4950 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4951 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4952 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4953 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4954 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4956 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4957 if(FAILED(hr)) shader_20 = NULL;
4959 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4960 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4961 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4962 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4963 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4964 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4966 hr = IDirect3DDevice9_BeginScene(device);
4967 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4968 if(SUCCEEDED(hr))
4970 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4971 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4973 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4975 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4978 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4980 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4981 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4983 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4985 if(shader_20) {
4986 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4987 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4989 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4992 hr = IDirect3DDevice9_EndScene(device);
4993 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4995 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4996 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4998 color = getPixelColor(device, 160, 360);
4999 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5000 "quad 1 has color %08x, expected 0x00808000\n", color);
5001 color = getPixelColor(device, 480, 360);
5002 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5003 "quad 2 has color %08x, expected 0x00808000\n", color);
5004 color = getPixelColor(device, 480, 120);
5005 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
5006 "quad 3 has color %08x, expected 0x00808000\n", color);
5007 if(shader_20) {
5008 color = getPixelColor(device, 160, 120);
5009 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
5010 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
5012 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5013 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5015 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5016 IDirect3DPixelShader9_Release(shader_14);
5017 IDirect3DPixelShader9_Release(shader_12);
5018 IDirect3DPixelShader9_Release(shader_11);
5021 static void dp2add_ps_test(IDirect3DDevice9 *device)
5023 IDirect3DPixelShader9 *shader_dp2add = NULL;
5024 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5025 HRESULT hr;
5026 DWORD color;
5028 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
5029 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5030 * source tokens can be constants. So, for this exercise, we move contents of c0 to
5031 * r0 first.
5032 * The result here for the r,g,b components should be roughly 0.5:
5033 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5034 static const DWORD shader_code_dp2add[] = {
5035 0xffff0200, /* ps_2_0 */
5036 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
5038 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5039 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
5041 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5042 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5043 0x0000ffff /* end */
5046 /* Test the _sat modifier, too. Result here should be:
5047 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5048 * _SAT: ==> 1.0
5049 * ADD: (1.0 + -0.5) = 0.5
5051 static const DWORD shader_code_dp2add_sat[] = {
5052 0xffff0200, /* ps_2_0 */
5053 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
5055 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5056 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
5057 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
5059 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
5060 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5061 0x0000ffff /* end */
5064 const float quad[] = {
5065 -1.0, -1.0, 0.1,
5066 1.0, -1.0, 0.1,
5067 -1.0, 1.0, 0.1,
5068 1.0, 1.0, 0.1
5072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5073 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5075 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5076 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5078 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5079 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5082 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5084 if (shader_dp2add) {
5086 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5087 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5089 hr = IDirect3DDevice9_BeginScene(device);
5090 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5091 if(SUCCEEDED(hr))
5093 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5094 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5096 hr = IDirect3DDevice9_EndScene(device);
5097 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5100 color = getPixelColor(device, 360, 240);
5101 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5102 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5104 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5105 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5107 IDirect3DPixelShader9_Release(shader_dp2add);
5108 } else {
5109 skip("dp2add shader creation failed\n");
5112 if (shader_dp2add_sat) {
5114 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5115 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5117 hr = IDirect3DDevice9_BeginScene(device);
5118 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5119 if(SUCCEEDED(hr))
5121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5122 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5124 hr = IDirect3DDevice9_EndScene(device);
5125 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5128 color = getPixelColor(device, 360, 240);
5129 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5130 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5132 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5133 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5135 IDirect3DPixelShader9_Release(shader_dp2add_sat);
5136 } else {
5137 skip("dp2add shader creation failed\n");
5140 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5141 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5144 static void cnd_test(IDirect3DDevice9 *device)
5146 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5147 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5148 HRESULT hr;
5149 DWORD color;
5150 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5151 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5152 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5154 DWORD shader_code_11[] = {
5155 0xffff0101, /* ps_1_1 */
5156 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5157 0x00000040, 0xb00f0000, /* texcoord t0 */
5158 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
5159 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5160 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5161 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5162 0x0000ffff /* end */
5164 DWORD shader_code_12[] = {
5165 0xffff0102, /* ps_1_2 */
5166 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5167 0x00000040, 0xb00f0000, /* texcoord t0 */
5168 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5169 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
5170 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5171 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5172 0x0000ffff /* end */
5174 DWORD shader_code_13[] = {
5175 0xffff0103, /* ps_1_3 */
5176 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5177 0x00000040, 0xb00f0000, /* texcoord t0 */
5178 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5179 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
5180 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5181 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
5182 0x0000ffff /* end */
5184 DWORD shader_code_14[] = {
5185 0xffff0104, /* ps_1_3 */
5186 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5187 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5188 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5189 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
5190 0x0000ffff /* end */
5193 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5194 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5195 * set by the compiler, it was added manually after compilation. Note that the COISSUE
5196 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5197 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5198 * well enough.
5200 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5201 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
5202 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5203 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5205 DWORD shader_code_11_coissue[] = {
5206 0xffff0101, /* ps_1_1 */
5207 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5208 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5209 0x00000040, 0xb00f0000, /* texcoord t0 */
5210 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5211 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5212 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5213 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5214 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5215 /* 0x40000000 = D3DSI_COISSUE */
5216 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5217 0x0000ffff /* end */
5219 DWORD shader_code_12_coissue[] = {
5220 0xffff0102, /* ps_1_2 */
5221 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5222 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5223 0x00000040, 0xb00f0000, /* texcoord t0 */
5224 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5225 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5226 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5227 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5228 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5229 /* 0x40000000 = D3DSI_COISSUE */
5230 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5231 0x0000ffff /* end */
5233 DWORD shader_code_13_coissue[] = {
5234 0xffff0103, /* ps_1_3 */
5235 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
5236 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5237 0x00000040, 0xb00f0000, /* texcoord t0 */
5238 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5239 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
5240 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
5241 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
5242 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
5243 /* 0x40000000 = D3DSI_COISSUE */
5244 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
5245 0x0000ffff /* end */
5247 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5248 * compare against 0.5
5250 DWORD shader_code_14_coissue[] = {
5251 0xffff0104, /* ps_1_4 */
5252 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5253 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
5254 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
5255 /* 0x40000000 = D3DSI_COISSUE */
5256 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
5257 0x0000ffff /* end */
5259 float quad1[] = {
5260 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5261 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5262 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5263 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
5265 float quad2[] = {
5266 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
5267 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
5268 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
5269 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
5271 float quad3[] = {
5272 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5273 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5274 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5275 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
5277 float quad4[] = {
5278 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
5279 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
5280 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
5281 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
5283 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
5284 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
5285 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
5286 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
5288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5289 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5291 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5292 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5293 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5294 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5295 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5296 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5297 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5298 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5299 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5300 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5301 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5303 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5305 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5308 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5309 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5310 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5311 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5312 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5313 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5315 hr = IDirect3DDevice9_BeginScene(device);
5316 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5317 if(SUCCEEDED(hr))
5319 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5324 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5325 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5327 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5329 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5332 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5334 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5335 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5337 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5339 hr = IDirect3DDevice9_EndScene(device);
5340 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5343 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5344 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5346 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5347 color = getPixelColor(device, 158, 118);
5348 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5349 color = getPixelColor(device, 162, 118);
5350 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5351 color = getPixelColor(device, 158, 122);
5352 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5353 color = getPixelColor(device, 162, 122);
5354 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5356 /* 1.1 shader. All 3 components get set, based on the .w comparison */
5357 color = getPixelColor(device, 158, 358);
5358 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5359 color = getPixelColor(device, 162, 358);
5360 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5361 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5362 color = getPixelColor(device, 158, 362);
5363 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5364 color = getPixelColor(device, 162, 362);
5365 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5366 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5368 /* 1.2 shader */
5369 color = getPixelColor(device, 478, 358);
5370 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5371 color = getPixelColor(device, 482, 358);
5372 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5373 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5374 color = getPixelColor(device, 478, 362);
5375 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5376 color = getPixelColor(device, 482, 362);
5377 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5378 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5380 /* 1.3 shader */
5381 color = getPixelColor(device, 478, 118);
5382 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5383 color = getPixelColor(device, 482, 118);
5384 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5385 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5386 color = getPixelColor(device, 478, 122);
5387 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5388 color = getPixelColor(device, 482, 122);
5389 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5390 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5393 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5395 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5396 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5397 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5398 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5399 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5400 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5402 hr = IDirect3DDevice9_BeginScene(device);
5403 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5404 if(SUCCEEDED(hr))
5406 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5409 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5411 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5412 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5414 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5416 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5417 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5421 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5424 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5426 hr = IDirect3DDevice9_EndScene(device);
5427 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5430 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5431 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5433 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5434 * that we swapped the values in c1 and c2 to make the other tests return some color
5436 color = getPixelColor(device, 158, 118);
5437 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5438 color = getPixelColor(device, 162, 118);
5439 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5440 color = getPixelColor(device, 158, 122);
5441 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5442 color = getPixelColor(device, 162, 122);
5443 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5445 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5446 * (The Win7 nvidia driver always selects c2)
5448 color = getPixelColor(device, 158, 358);
5449 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5450 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5451 color = getPixelColor(device, 162, 358);
5452 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5453 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5454 color = getPixelColor(device, 158, 362);
5455 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5456 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5457 color = getPixelColor(device, 162, 362);
5458 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5459 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5461 /* 1.2 shader */
5462 color = getPixelColor(device, 478, 358);
5463 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5464 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5465 color = getPixelColor(device, 482, 358);
5466 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5467 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5468 color = getPixelColor(device, 478, 362);
5469 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5470 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5471 color = getPixelColor(device, 482, 362);
5472 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5473 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5475 /* 1.3 shader */
5476 color = getPixelColor(device, 478, 118);
5477 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5478 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5479 color = getPixelColor(device, 482, 118);
5480 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5481 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5482 color = getPixelColor(device, 478, 122);
5483 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5484 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5485 color = getPixelColor(device, 482, 122);
5486 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5487 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5489 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5490 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5492 IDirect3DPixelShader9_Release(shader_14_coissue);
5493 IDirect3DPixelShader9_Release(shader_13_coissue);
5494 IDirect3DPixelShader9_Release(shader_12_coissue);
5495 IDirect3DPixelShader9_Release(shader_11_coissue);
5496 IDirect3DPixelShader9_Release(shader_14);
5497 IDirect3DPixelShader9_Release(shader_13);
5498 IDirect3DPixelShader9_Release(shader_12);
5499 IDirect3DPixelShader9_Release(shader_11);
5502 static void nested_loop_test(IDirect3DDevice9 *device) {
5503 const DWORD shader_code[] = {
5504 0xffff0300, /* ps_3_0 */
5505 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5506 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5507 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5508 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5509 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5510 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5511 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5512 0x0000001d, /* endloop */
5513 0x0000001d, /* endloop */
5514 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5515 0x0000ffff /* end */
5517 const DWORD vshader_code[] = {
5518 0xfffe0300, /* vs_3_0 */
5519 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5520 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5521 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5522 0x0000ffff /* end */
5524 IDirect3DPixelShader9 *shader;
5525 IDirect3DVertexShader9 *vshader;
5526 HRESULT hr;
5527 DWORD color;
5528 const float quad[] = {
5529 -1.0, -1.0, 0.1,
5530 1.0, -1.0, 0.1,
5531 -1.0, 1.0, 0.1,
5532 1.0, 1.0, 0.1
5535 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5536 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5537 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5538 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5539 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5540 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5541 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5543 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5544 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5545 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5546 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5548 hr = IDirect3DDevice9_BeginScene(device);
5549 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5550 if(SUCCEEDED(hr))
5552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5553 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5554 hr = IDirect3DDevice9_EndScene(device);
5555 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5558 color = getPixelColor(device, 360, 240);
5559 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5560 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5562 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5563 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5565 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5567 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5568 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5569 IDirect3DPixelShader9_Release(shader);
5570 IDirect3DVertexShader9_Release(vshader);
5573 struct varying_test_struct
5575 const DWORD *shader_code;
5576 IDirect3DPixelShader9 *shader;
5577 DWORD color, color_rhw;
5578 const char *name;
5579 BOOL todo, todo_rhw;
5582 struct hugeVertex
5584 float pos_x, pos_y, pos_z, rhw;
5585 float weight_1, weight_2, weight_3, weight_4;
5586 float index_1, index_2, index_3, index_4;
5587 float normal_1, normal_2, normal_3, normal_4;
5588 float fog_1, fog_2, fog_3, fog_4;
5589 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5590 float tangent_1, tangent_2, tangent_3, tangent_4;
5591 float binormal_1, binormal_2, binormal_3, binormal_4;
5592 float depth_1, depth_2, depth_3, depth_4;
5593 DWORD diffuse, specular;
5596 static void pretransformed_varying_test(IDirect3DDevice9 *device) {
5597 /* dcl_position: fails to compile */
5598 const DWORD blendweight_code[] = {
5599 0xffff0300, /* ps_3_0 */
5600 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5601 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5602 0x0000ffff /* end */
5604 const DWORD blendindices_code[] = {
5605 0xffff0300, /* ps_3_0 */
5606 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5607 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5608 0x0000ffff /* end */
5610 const DWORD normal_code[] = {
5611 0xffff0300, /* ps_3_0 */
5612 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5613 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5614 0x0000ffff /* end */
5616 /* psize: fails? */
5617 const DWORD texcoord0_code[] = {
5618 0xffff0300, /* ps_3_0 */
5619 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5620 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5621 0x0000ffff /* end */
5623 const DWORD tangent_code[] = {
5624 0xffff0300, /* ps_3_0 */
5625 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5626 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5627 0x0000ffff /* end */
5629 const DWORD binormal_code[] = {
5630 0xffff0300, /* ps_3_0 */
5631 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5632 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5633 0x0000ffff /* end */
5635 /* tessfactor: fails */
5636 /* positiont: fails */
5637 const DWORD color_code[] = {
5638 0xffff0300, /* ps_3_0 */
5639 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5640 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5641 0x0000ffff /* end */
5643 const DWORD fog_code[] = {
5644 0xffff0300, /* ps_3_0 */
5645 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5646 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5647 0x0000ffff /* end */
5649 const DWORD depth_code[] = {
5650 0xffff0300, /* ps_3_0 */
5651 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5652 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5653 0x0000ffff /* end */
5655 const DWORD specular_code[] = {
5656 0xffff0300, /* ps_3_0 */
5657 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5658 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5659 0x0000ffff /* end */
5661 /* sample: fails */
5663 struct varying_test_struct tests[] = {
5664 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5665 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5666 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5667 /* Why does dx not forward the texcoord? */
5668 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5669 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5670 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5671 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5672 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5673 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5674 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5676 /* Declare a monster vertex type :-) */
5677 static const D3DVERTEXELEMENT9 decl_elements[] = {
5678 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5679 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5680 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5681 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5682 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5683 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5684 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5685 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5686 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5687 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5688 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5689 D3DDECL_END()
5691 struct hugeVertex data[4] = {
5693 -1.0, -1.0, 0.1, 1.0,
5694 0.1, 0.1, 0.1, 0.1,
5695 0.2, 0.2, 0.2, 0.2,
5696 0.3, 0.3, 0.3, 0.3,
5697 0.4, 0.4, 0.4, 0.4,
5698 0.50, 0.55, 0.55, 0.55,
5699 0.6, 0.6, 0.6, 0.7,
5700 0.7, 0.7, 0.7, 0.6,
5701 0.8, 0.8, 0.8, 0.8,
5702 0xe6e6e6e6, /* 0.9 * 256 */
5703 0x224488ff /* Nothing special */
5706 1.0, -1.0, 0.1, 1.0,
5707 0.1, 0.1, 0.1, 0.1,
5708 0.2, 0.2, 0.2, 0.2,
5709 0.3, 0.3, 0.3, 0.3,
5710 0.4, 0.4, 0.4, 0.4,
5711 0.50, 0.55, 0.55, 0.55,
5712 0.6, 0.6, 0.6, 0.7,
5713 0.7, 0.7, 0.7, 0.6,
5714 0.8, 0.8, 0.8, 0.8,
5715 0xe6e6e6e6, /* 0.9 * 256 */
5716 0x224488ff /* Nothing special */
5719 -1.0, 1.0, 0.1, 1.0,
5720 0.1, 0.1, 0.1, 0.1,
5721 0.2, 0.2, 0.2, 0.2,
5722 0.3, 0.3, 0.3, 0.3,
5723 0.4, 0.4, 0.4, 0.4,
5724 0.50, 0.55, 0.55, 0.55,
5725 0.6, 0.6, 0.6, 0.7,
5726 0.7, 0.7, 0.7, 0.6,
5727 0.8, 0.8, 0.8, 0.8,
5728 0xe6e6e6e6, /* 0.9 * 256 */
5729 0x224488ff /* Nothing special */
5732 1.0, 1.0, 0.1, 1.0,
5733 0.1, 0.1, 0.1, 0.1,
5734 0.2, 0.2, 0.2, 0.2,
5735 0.3, 0.3, 0.3, 0.3,
5736 0.4, 0.4, 0.4, 0.4,
5737 0.50, 0.55, 0.55, 0.55,
5738 0.6, 0.6, 0.6, 0.7,
5739 0.7, 0.7, 0.7, 0.6,
5740 0.8, 0.8, 0.8, 0.8,
5741 0xe6e6e6e6, /* 0.9 * 256 */
5742 0x224488ff /* Nothing special */
5745 struct hugeVertex data2[4];
5746 IDirect3DVertexDeclaration9 *decl;
5747 HRESULT hr;
5748 unsigned int i;
5749 DWORD color, r, g, b, r_e, g_e, b_e;
5751 memcpy(data2, data, sizeof(data2));
5752 data2[0].pos_x = 0; data2[0].pos_y = 0;
5753 data2[1].pos_x = 640; data2[1].pos_y = 0;
5754 data2[2].pos_x = 0; data2[2].pos_y = 480;
5755 data2[3].pos_x = 640; data2[3].pos_y = 480;
5757 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5758 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5759 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5760 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5762 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5764 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5765 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5766 tests[i].name, hr);
5769 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5770 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5771 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5776 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5777 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5779 hr = IDirect3DDevice9_BeginScene(device);
5780 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5781 if(SUCCEEDED(hr))
5783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5784 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5785 hr = IDirect3DDevice9_EndScene(device);
5786 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5789 color = getPixelColor(device, 360, 240);
5790 r = color & 0x00ff0000 >> 16;
5791 g = color & 0x0000ff00 >> 8;
5792 b = color & 0x000000ff;
5793 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5794 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5795 b_e = tests[i].color_rhw & 0x000000ff;
5797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5798 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5800 if(tests[i].todo_rhw) {
5801 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5802 * pipeline
5804 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5805 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5806 tests[i].name, color, tests[i].color_rhw);
5807 } else {
5808 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5809 "Test %s returned color 0x%08x, expected 0x%08x\n",
5810 tests[i].name, color, tests[i].color_rhw);
5814 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5816 IDirect3DPixelShader9_Release(tests[i].shader);
5819 IDirect3DVertexDeclaration9_Release(decl);
5822 static void test_compare_instructions(IDirect3DDevice9 *device)
5824 DWORD shader_sge_vec_code[] = {
5825 0xfffe0101, /* vs_1_1 */
5826 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5827 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5828 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5829 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5830 0x0000ffff /* end */
5832 DWORD shader_slt_vec_code[] = {
5833 0xfffe0101, /* vs_1_1 */
5834 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5835 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5836 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5837 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5838 0x0000ffff /* end */
5840 DWORD shader_sge_scalar_code[] = {
5841 0xfffe0101, /* vs_1_1 */
5842 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5843 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5844 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5845 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5846 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5847 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5848 0x0000ffff /* end */
5850 DWORD shader_slt_scalar_code[] = {
5851 0xfffe0101, /* vs_1_1 */
5852 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5853 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5854 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5855 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5856 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5857 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5858 0x0000ffff /* end */
5860 IDirect3DVertexShader9 *shader_sge_vec;
5861 IDirect3DVertexShader9 *shader_slt_vec;
5862 IDirect3DVertexShader9 *shader_sge_scalar;
5863 IDirect3DVertexShader9 *shader_slt_scalar;
5864 HRESULT hr, color;
5865 float quad1[] = {
5866 -1.0, -1.0, 0.1,
5867 0.0, -1.0, 0.1,
5868 -1.0, 0.0, 0.1,
5869 0.0, 0.0, 0.1
5871 float quad2[] = {
5872 0.0, -1.0, 0.1,
5873 1.0, -1.0, 0.1,
5874 0.0, 0.0, 0.1,
5875 1.0, 0.0, 0.1
5877 float quad3[] = {
5878 -1.0, 0.0, 0.1,
5879 0.0, 0.0, 0.1,
5880 -1.0, 1.0, 0.1,
5881 0.0, 1.0, 0.1
5883 float quad4[] = {
5884 0.0, 0.0, 0.1,
5885 1.0, 0.0, 0.1,
5886 0.0, 1.0, 0.1,
5887 1.0, 1.0, 0.1
5889 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5890 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5893 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5895 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5896 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5897 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5898 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5899 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5900 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5901 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5902 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5903 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5904 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5905 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5906 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5908 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5910 hr = IDirect3DDevice9_BeginScene(device);
5911 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5912 if(SUCCEEDED(hr))
5914 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5915 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5917 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5919 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5920 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5921 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5922 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5924 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5925 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5926 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5927 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5929 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5930 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5932 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5933 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5935 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5937 hr = IDirect3DDevice9_EndScene(device);
5938 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5941 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5942 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5944 color = getPixelColor(device, 160, 360);
5945 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5946 color = getPixelColor(device, 480, 360);
5947 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5948 color = getPixelColor(device, 160, 120);
5949 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5950 color = getPixelColor(device, 480, 160);
5951 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5953 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5956 IDirect3DVertexShader9_Release(shader_sge_vec);
5957 IDirect3DVertexShader9_Release(shader_slt_vec);
5958 IDirect3DVertexShader9_Release(shader_sge_scalar);
5959 IDirect3DVertexShader9_Release(shader_slt_scalar);
5962 static void test_vshader_input(IDirect3DDevice9 *device)
5964 static const DWORD swapped_shader_code_3[] =
5966 0xfffe0300, /* vs_3_0 */
5967 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5968 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5969 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5970 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5971 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5972 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5973 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5974 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5975 0x0000ffff /* end */
5977 static const DWORD swapped_shader_code_1[] =
5979 0xfffe0101, /* vs_1_1 */
5980 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5981 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5982 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5983 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5984 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5985 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5986 0x0000ffff /* end */
5988 static const DWORD swapped_shader_code_2[] =
5990 0xfffe0200, /* vs_2_0 */
5991 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5992 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5993 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5994 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5995 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5996 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5997 0x0000ffff /* end */
5999 static const DWORD texcoord_color_shader_code_3[] =
6001 0xfffe0300, /* vs_3_0 */
6002 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6003 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6004 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6005 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6006 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6007 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
6008 0x0000ffff /* end */
6010 static const DWORD texcoord_color_shader_code_2[] =
6012 0xfffe0200, /* vs_2_0 */
6013 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6014 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6015 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6016 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6017 0x0000ffff /* end */
6019 static const DWORD texcoord_color_shader_code_1[] =
6021 0xfffe0101, /* vs_1_1 */
6022 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6023 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
6024 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6025 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
6026 0x0000ffff /* end */
6028 static const DWORD color_color_shader_code_3[] =
6030 0xfffe0300, /* vs_3_0 */
6031 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6032 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
6033 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6034 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6035 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6036 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
6037 0x0000ffff /* end */
6039 static const DWORD color_color_shader_code_2[] =
6041 0xfffe0200, /* vs_2_0 */
6042 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6043 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6044 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6045 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6046 0x0000ffff /* end */
6048 static const DWORD color_color_shader_code_1[] =
6050 0xfffe0101, /* vs_1_1 */
6051 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6052 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
6053 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6054 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
6055 0x0000ffff /* end */
6057 static const DWORD ps3_code[] =
6059 0xffff0300, /* ps_3_0 */
6060 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
6061 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6062 0x0000ffff /* end */
6064 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6065 IDirect3DPixelShader9 *ps;
6066 HRESULT hr;
6067 DWORD color;
6068 float quad1[] = {
6069 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6070 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6071 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6072 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6074 float quad2[] = {
6075 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6076 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6077 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6078 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6080 float quad3[] = {
6081 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6082 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6083 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6084 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6086 float quad4[] = {
6087 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6088 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6089 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6090 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6092 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6093 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6094 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6095 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6096 D3DDECL_END()
6098 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6099 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6100 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6101 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6102 D3DDECL_END()
6104 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6105 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6106 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6107 D3DDECL_END()
6109 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6110 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6111 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6112 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6113 D3DDECL_END()
6115 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6116 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6117 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6118 D3DDECL_END()
6120 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6121 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6122 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6123 D3DDECL_END()
6125 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6126 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6127 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6128 D3DDECL_END()
6130 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6131 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6132 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6133 D3DDECL_END()
6135 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6136 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6137 unsigned int i;
6138 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6139 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6141 struct vertex quad1_color[] = {
6142 {-1.0, -1.0, 0.1, 0x00ff8040},
6143 { 0.0, -1.0, 0.1, 0x00ff8040},
6144 {-1.0, 0.0, 0.1, 0x00ff8040},
6145 { 0.0, 0.0, 0.1, 0x00ff8040}
6147 struct vertex quad2_color[] = {
6148 { 0.0, -1.0, 0.1, 0x00ff8040},
6149 { 1.0, -1.0, 0.1, 0x00ff8040},
6150 { 0.0, 0.0, 0.1, 0x00ff8040},
6151 { 1.0, 0.0, 0.1, 0x00ff8040}
6153 struct vertex quad3_color[] = {
6154 {-1.0, 0.0, 0.1, 0x00ff8040},
6155 { 0.0, 0.0, 0.1, 0x00ff8040},
6156 {-1.0, 1.0, 0.1, 0x00ff8040},
6157 { 0.0, 1.0, 0.1, 0x00ff8040}
6159 float quad4_color[] = {
6160 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6161 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6162 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6163 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6166 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6167 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6168 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6169 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6170 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6171 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6172 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6173 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6175 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6176 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6177 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6178 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6179 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6181 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6182 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6184 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
6185 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6187 for(i = 1; i <= 3; i++) {
6188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6189 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6190 if(i == 3) {
6191 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6192 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6193 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6194 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6195 } else if(i == 2){
6196 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6197 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6198 } else if(i == 1) {
6199 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6200 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6203 hr = IDirect3DDevice9_BeginScene(device);
6204 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6205 if(SUCCEEDED(hr))
6207 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6208 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6210 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6213 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6215 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6216 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6218 if(i == 3 || i == 2) {
6219 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6220 } else if(i == 1) {
6221 /* Succeeds or fails, depending on SW or HW vertex processing */
6222 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6225 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6228 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6230 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6233 if(i == 3 || i == 2) {
6234 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6235 } else if(i == 1) {
6236 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6239 hr = IDirect3DDevice9_EndScene(device);
6240 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6243 if(i == 3 || i == 2) {
6244 color = getPixelColor(device, 160, 360);
6245 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6246 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6248 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6249 color = getPixelColor(device, 480, 360);
6250 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6251 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6252 color = getPixelColor(device, 160, 120);
6253 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6254 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6255 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6257 color = getPixelColor(device, 480, 160);
6258 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6259 } else if(i == 1) {
6260 color = getPixelColor(device, 160, 360);
6261 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6262 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6263 color = getPixelColor(device, 480, 360);
6264 /* Accept the clear color as well in this case, since SW VP returns an error */
6265 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6266 color = getPixelColor(device, 160, 120);
6267 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6268 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6269 color = getPixelColor(device, 480, 160);
6270 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6273 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6274 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6277 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6279 /* Now find out if the whole streams are re-read, or just the last active value for the
6280 * vertices is used.
6282 hr = IDirect3DDevice9_BeginScene(device);
6283 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6284 if(SUCCEEDED(hr))
6286 float quad1_modified[] = {
6287 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6288 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6289 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6290 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6292 float quad2_modified[] = {
6293 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6294 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6295 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6296 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6299 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6302 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6303 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6305 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6307 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6310 if(i == 3 || i == 2) {
6311 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6312 } else if(i == 1) {
6313 /* Succeeds or fails, depending on SW or HW vertex processing */
6314 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6317 hr = IDirect3DDevice9_EndScene(device);
6318 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6321 color = getPixelColor(device, 480, 350);
6322 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6323 * as well.
6325 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6326 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6327 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6328 * refrast's result.
6330 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6332 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6333 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6336 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6338 IDirect3DDevice9_SetVertexShader(device, NULL);
6339 IDirect3DDevice9_SetPixelShader(device, NULL);
6340 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6342 IDirect3DVertexShader9_Release(swapped_shader);
6345 for(i = 1; i <= 3; i++) {
6346 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6347 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6348 if(i == 3) {
6349 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6350 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6351 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6352 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6353 hr = IDirect3DDevice9_SetPixelShader(device, ps);
6354 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6355 } else if(i == 2){
6356 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6358 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6359 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6360 } else if(i == 1) {
6361 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6362 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6363 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6364 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6367 hr = IDirect3DDevice9_BeginScene(device);
6368 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6369 if(SUCCEEDED(hr))
6371 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6372 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6373 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6374 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6376 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6378 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6379 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6381 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6382 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6383 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6384 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6386 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6388 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6389 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6390 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6393 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6395 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6396 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6398 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6400 hr = IDirect3DDevice9_EndScene(device);
6401 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6403 IDirect3DDevice9_SetVertexShader(device, NULL);
6404 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6405 IDirect3DDevice9_SetPixelShader(device, NULL);
6407 color = getPixelColor(device, 160, 360);
6408 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6409 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6410 color = getPixelColor(device, 480, 360);
6411 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6412 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6413 color = getPixelColor(device, 160, 120);
6414 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6415 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6416 color = getPixelColor(device, 480, 160);
6417 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6418 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6420 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6421 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6423 IDirect3DVertexShader9_Release(texcoord_color_shader);
6424 IDirect3DVertexShader9_Release(color_color_shader);
6427 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6428 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6429 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6430 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6432 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6433 IDirect3DVertexDeclaration9_Release(decl_color_color);
6434 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6435 IDirect3DVertexDeclaration9_Release(decl_color_float);
6437 IDirect3DPixelShader9_Release(ps);
6440 static void srgbtexture_test(IDirect3DDevice9 *device)
6442 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6443 * texture stage state to render a quad using that texture. The resulting
6444 * color components should be 0x36 (~ 0.21), per this formula:
6445 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6446 * This is true where srgb_color > 0.04045.
6448 IDirect3D9 *d3d = NULL;
6449 HRESULT hr;
6450 LPDIRECT3DTEXTURE9 texture = NULL;
6451 LPDIRECT3DSURFACE9 surface = NULL;
6452 D3DLOCKED_RECT lr;
6453 DWORD color;
6454 float quad[] = {
6455 -1.0, 1.0, 0.0, 0.0, 0.0,
6456 1.0, 1.0, 0.0, 1.0, 0.0,
6457 -1.0, -1.0, 0.0, 0.0, 1.0,
6458 1.0, -1.0, 0.0, 1.0, 1.0,
6462 memset(&lr, 0, sizeof(lr));
6463 IDirect3DDevice9_GetDirect3D(device, &d3d);
6464 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6465 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6466 D3DFMT_A8R8G8B8) != D3D_OK) {
6467 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6468 goto out;
6471 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6472 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6473 &texture, NULL);
6474 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6475 if(!texture) {
6476 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6477 goto out;
6479 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6480 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6482 fill_surface(surface, 0xff7f7f7f);
6483 IDirect3DSurface9_Release(surface);
6485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6486 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6487 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6488 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6490 hr = IDirect3DDevice9_BeginScene(device);
6491 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6492 if(SUCCEEDED(hr))
6494 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6495 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6497 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6498 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6501 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6502 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6504 hr = IDirect3DDevice9_EndScene(device);
6505 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6508 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6509 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6510 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6511 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6513 color = getPixelColor(device, 320, 240);
6514 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6516 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6517 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6519 out:
6520 if(texture) IDirect3DTexture9_Release(texture);
6521 IDirect3D9_Release(d3d);
6524 static void shademode_test(IDirect3DDevice9 *device)
6526 /* Render a quad and try all of the different fixed function shading models. */
6527 HRESULT hr;
6528 DWORD color0, color1;
6529 DWORD color0_gouraud = 0, color1_gouraud = 0;
6530 DWORD shademode = D3DSHADE_FLAT;
6531 DWORD primtype = D3DPT_TRIANGLESTRIP;
6532 LPVOID data = NULL;
6533 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6534 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6535 UINT i, j;
6536 struct vertex quad_strip[] =
6538 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6539 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6540 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6541 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6543 struct vertex quad_list[] =
6545 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6546 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6547 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6549 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6550 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6551 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6554 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6555 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6556 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6557 if (FAILED(hr)) goto bail;
6559 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6560 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6561 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6562 if (FAILED(hr)) goto bail;
6564 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6565 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6567 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6568 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6570 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6571 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6572 memcpy(data, quad_strip, sizeof(quad_strip));
6573 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6574 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6576 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6577 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6578 memcpy(data, quad_list, sizeof(quad_list));
6579 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6580 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6582 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6583 * the color fixups we have to do for FLAT shading will be dependent on that. */
6584 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6585 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6587 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6588 for (j=0; j<2; j++) {
6590 /* Inner loop just changes the D3DRS_SHADEMODE */
6591 for (i=0; i<3; i++) {
6592 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6593 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6596 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6598 hr = IDirect3DDevice9_BeginScene(device);
6599 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6600 if(SUCCEEDED(hr))
6602 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6603 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6605 hr = IDirect3DDevice9_EndScene(device);
6606 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6609 /* Sample two spots from the output */
6610 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6611 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6612 switch(shademode) {
6613 case D3DSHADE_FLAT:
6614 /* Should take the color of the first vertex of each triangle */
6615 if (0)
6617 /* This test depends on EXT_provoking_vertex being
6618 * available. This extension is currently (20090810)
6619 * not common enough to let the test fail if it isn't
6620 * present. */
6621 ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6622 ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6624 shademode = D3DSHADE_GOURAUD;
6625 break;
6626 case D3DSHADE_GOURAUD:
6627 /* Should be an interpolated blend */
6629 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6630 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6631 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6632 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6634 color0_gouraud = color0;
6635 color1_gouraud = color1;
6637 shademode = D3DSHADE_PHONG;
6638 break;
6639 case D3DSHADE_PHONG:
6640 /* Should be the same as GOURAUD, since no hardware implements this */
6641 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6642 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6643 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6644 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6646 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6647 color0_gouraud, color0);
6648 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6649 color1_gouraud, color1);
6650 break;
6654 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6655 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6657 /* Now, do it all over again with a TRIANGLELIST */
6658 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6659 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6660 primtype = D3DPT_TRIANGLELIST;
6661 shademode = D3DSHADE_FLAT;
6664 bail:
6665 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6666 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6667 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6668 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6670 if (vb_strip)
6671 IDirect3DVertexBuffer9_Release(vb_strip);
6672 if (vb_list)
6673 IDirect3DVertexBuffer9_Release(vb_list);
6676 static void alpha_test(IDirect3DDevice9 *device)
6678 HRESULT hr;
6679 IDirect3DTexture9 *offscreenTexture;
6680 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6681 DWORD color;
6683 struct vertex quad1[] =
6685 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6686 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6687 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6688 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6690 struct vertex quad2[] =
6692 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6693 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6694 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6695 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6697 static const float composite_quad[][5] = {
6698 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6699 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6700 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6701 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6704 /* Clear the render target with alpha = 0.5 */
6705 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6706 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6708 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6709 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6711 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6712 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6713 if(!backbuffer) {
6714 goto out;
6717 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6718 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6719 if(!offscreen) {
6720 goto out;
6723 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6726 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6727 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6729 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6730 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6731 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6732 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6733 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6735 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6738 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6739 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6741 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6745 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6747 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6749 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6752 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6754 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6756 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6757 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6758 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6759 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6760 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6762 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6765 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6767 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6769 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6772 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6774 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6776 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6778 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6779 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6781 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6782 * Disable alpha blending for the final composition
6784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6785 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6786 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6787 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6789 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6790 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6792 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6793 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6794 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6796 hr = IDirect3DDevice9_EndScene(device);
6797 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6800 color = getPixelColor(device, 160, 360);
6801 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6802 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6804 color = getPixelColor(device, 160, 120);
6805 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6806 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6808 color = getPixelColor(device, 480, 360);
6809 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6810 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6812 color = getPixelColor(device, 480, 120);
6813 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6814 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6816 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6818 out:
6819 /* restore things */
6820 if(backbuffer) {
6821 IDirect3DSurface9_Release(backbuffer);
6823 if(offscreenTexture) {
6824 IDirect3DTexture9_Release(offscreenTexture);
6826 if(offscreen) {
6827 IDirect3DSurface9_Release(offscreen);
6831 struct vertex_shortcolor {
6832 float x, y, z;
6833 unsigned short r, g, b, a;
6835 struct vertex_floatcolor {
6836 float x, y, z;
6837 float r, g, b, a;
6840 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6842 HRESULT hr;
6843 BOOL s_ok, ub_ok, f_ok;
6844 DWORD color, size, i;
6845 void *data;
6846 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6847 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6848 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6849 D3DDECL_END()
6851 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6852 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6853 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6854 D3DDECL_END()
6856 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6857 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6858 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6859 D3DDECL_END()
6861 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6862 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6863 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6864 D3DDECL_END()
6866 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6867 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6868 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6869 D3DDECL_END()
6871 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6872 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6873 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6874 D3DDECL_END()
6876 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6877 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6878 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6879 D3DDECL_END()
6881 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6882 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6883 IDirect3DVertexBuffer9 *vb, *vb2;
6884 struct vertex quad1[] = /* D3DCOLOR */
6886 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6887 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6888 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6889 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6891 struct vertex quad2[] = /* UBYTE4N */
6893 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6894 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6895 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6896 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6898 struct vertex_shortcolor quad3[] = /* short */
6900 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6901 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6902 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6903 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6905 struct vertex_floatcolor quad4[] =
6907 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6908 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6909 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6910 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6912 DWORD colors[] = {
6913 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6914 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6915 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6916 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6917 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6918 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6919 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6920 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6921 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6922 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6923 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6924 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6925 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6926 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6927 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6928 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6930 float quads[] = {
6931 -1.0, -1.0, 0.1,
6932 -1.0, 0.0, 0.1,
6933 0.0, -1.0, 0.1,
6934 0.0, 0.0, 0.1,
6936 0.0, -1.0, 0.1,
6937 0.0, 0.0, 0.1,
6938 1.0, -1.0, 0.1,
6939 1.0, 0.0, 0.1,
6941 0.0, 0.0, 0.1,
6942 0.0, 1.0, 0.1,
6943 1.0, 0.0, 0.1,
6944 1.0, 1.0, 0.1,
6946 -1.0, 0.0, 0.1,
6947 -1.0, 1.0, 0.1,
6948 0.0, 0.0, 0.1,
6949 0.0, 1.0, 0.1
6951 struct tvertex quad_transformed[] = {
6952 { 90, 110, 0.1, 2.0, 0x00ffff00},
6953 { 570, 110, 0.1, 2.0, 0x00ffff00},
6954 { 90, 300, 0.1, 2.0, 0x00ffff00},
6955 { 570, 300, 0.1, 2.0, 0x00ffff00}
6957 D3DCAPS9 caps;
6959 memset(&caps, 0, sizeof(caps));
6960 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6961 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6963 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6964 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6966 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6967 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6968 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6969 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6970 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6971 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6972 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6973 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6974 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6975 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6976 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6977 } else {
6978 trace("D3DDTCAPS_UBYTE4N not supported\n");
6979 dcl_ubyte_2 = NULL;
6980 dcl_ubyte = NULL;
6982 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6983 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6984 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6985 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6987 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6988 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6989 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6990 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6992 hr = IDirect3DDevice9_BeginScene(device);
6993 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6994 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6995 if(SUCCEEDED(hr)) {
6996 if(dcl_color) {
6997 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6999 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7000 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7003 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7004 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7005 * using software vertex processing. Doh!
7007 if(dcl_ubyte) {
7008 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7009 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7010 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7011 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7012 ub_ok = SUCCEEDED(hr);
7015 if(dcl_short) {
7016 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7017 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7018 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7019 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7020 s_ok = SUCCEEDED(hr);
7023 if(dcl_float) {
7024 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7025 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7027 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7028 f_ok = SUCCEEDED(hr);
7031 hr = IDirect3DDevice9_EndScene(device);
7032 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7035 if(dcl_short) {
7036 color = getPixelColor(device, 480, 360);
7037 ok(color == 0x000000ff || !s_ok,
7038 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7040 if(dcl_ubyte) {
7041 color = getPixelColor(device, 160, 120);
7042 ok(color == 0x0000ffff || !ub_ok,
7043 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7045 if(dcl_color) {
7046 color = getPixelColor(device, 160, 360);
7047 ok(color == 0x00ffff00,
7048 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7050 if(dcl_float) {
7051 color = getPixelColor(device, 480, 120);
7052 ok(color == 0x00ff0000 || !f_ok,
7053 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7055 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7057 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7058 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7059 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7060 * whether the immediate mode code works
7062 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7063 hr = IDirect3DDevice9_BeginScene(device);
7064 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7065 if(SUCCEEDED(hr)) {
7066 if(dcl_color) {
7067 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7068 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7069 memcpy(data, quad1, sizeof(quad1));
7070 hr = IDirect3DVertexBuffer9_Unlock(vb);
7071 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7072 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7073 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7074 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7075 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7076 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7077 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7080 if(dcl_ubyte) {
7081 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7082 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7083 memcpy(data, quad2, sizeof(quad2));
7084 hr = IDirect3DVertexBuffer9_Unlock(vb);
7085 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7086 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7088 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7089 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7090 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7091 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7092 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7093 ub_ok = SUCCEEDED(hr);
7096 if(dcl_short) {
7097 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7098 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7099 memcpy(data, quad3, sizeof(quad3));
7100 hr = IDirect3DVertexBuffer9_Unlock(vb);
7101 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7102 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7103 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7104 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7105 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7106 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7107 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7108 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7109 s_ok = SUCCEEDED(hr);
7112 if(dcl_float) {
7113 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7114 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7115 memcpy(data, quad4, sizeof(quad4));
7116 hr = IDirect3DVertexBuffer9_Unlock(vb);
7117 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7118 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7119 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7120 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7121 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7122 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7123 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7124 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7125 f_ok = SUCCEEDED(hr);
7128 hr = IDirect3DDevice9_EndScene(device);
7129 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7132 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7133 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7134 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7135 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7137 if(dcl_short) {
7138 color = getPixelColor(device, 480, 360);
7139 ok(color == 0x000000ff || !s_ok,
7140 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7142 if(dcl_ubyte) {
7143 color = getPixelColor(device, 160, 120);
7144 ok(color == 0x0000ffff || !ub_ok,
7145 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7147 if(dcl_color) {
7148 color = getPixelColor(device, 160, 360);
7149 ok(color == 0x00ffff00,
7150 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7152 if(dcl_float) {
7153 color = getPixelColor(device, 480, 120);
7154 ok(color == 0x00ff0000 || !f_ok,
7155 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7157 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7159 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7160 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7162 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7163 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7164 memcpy(data, quad_transformed, sizeof(quad_transformed));
7165 hr = IDirect3DVertexBuffer9_Unlock(vb);
7166 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7168 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7169 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7171 hr = IDirect3DDevice9_BeginScene(device);
7172 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7173 if(SUCCEEDED(hr)) {
7174 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7175 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7176 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7177 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7179 hr = IDirect3DDevice9_EndScene(device);
7180 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7183 color = getPixelColor(device, 88, 108);
7184 ok(color == 0x000000ff,
7185 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7186 color = getPixelColor(device, 92, 108);
7187 ok(color == 0x000000ff,
7188 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7189 color = getPixelColor(device, 88, 112);
7190 ok(color == 0x000000ff,
7191 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7192 color = getPixelColor(device, 92, 112);
7193 ok(color == 0x00ffff00,
7194 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7196 color = getPixelColor(device, 568, 108);
7197 ok(color == 0x000000ff,
7198 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7199 color = getPixelColor(device, 572, 108);
7200 ok(color == 0x000000ff,
7201 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7202 color = getPixelColor(device, 568, 112);
7203 ok(color == 0x00ffff00,
7204 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7205 color = getPixelColor(device, 572, 112);
7206 ok(color == 0x000000ff,
7207 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7209 color = getPixelColor(device, 88, 298);
7210 ok(color == 0x000000ff,
7211 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7212 color = getPixelColor(device, 92, 298);
7213 ok(color == 0x00ffff00,
7214 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7215 color = getPixelColor(device, 88, 302);
7216 ok(color == 0x000000ff,
7217 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7218 color = getPixelColor(device, 92, 302);
7219 ok(color == 0x000000ff,
7220 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7222 color = getPixelColor(device, 568, 298);
7223 ok(color == 0x00ffff00,
7224 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7225 color = getPixelColor(device, 572, 298);
7226 ok(color == 0x000000ff,
7227 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7228 color = getPixelColor(device, 568, 302);
7229 ok(color == 0x000000ff,
7230 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7231 color = getPixelColor(device, 572, 302);
7232 ok(color == 0x000000ff,
7233 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7235 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7237 /* This test is pointless without those two declarations: */
7238 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7239 skip("color-ubyte switching test declarations aren't supported\n");
7240 goto out;
7243 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7244 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7245 memcpy(data, quads, sizeof(quads));
7246 hr = IDirect3DVertexBuffer9_Unlock(vb);
7247 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7248 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7249 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7250 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7251 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7252 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7253 memcpy(data, colors, sizeof(colors));
7254 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7255 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7257 for(i = 0; i < 2; i++) {
7258 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7259 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7261 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7262 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7263 if(i == 0) {
7264 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7265 } else {
7266 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7268 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7270 hr = IDirect3DDevice9_BeginScene(device);
7271 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7272 ub_ok = FALSE;
7273 if(SUCCEEDED(hr)) {
7274 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7275 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7276 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7277 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7278 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7279 ub_ok = SUCCEEDED(hr);
7281 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7282 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7283 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7284 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7286 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7287 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7288 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7289 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7290 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7291 ub_ok = (SUCCEEDED(hr) && ub_ok);
7293 hr = IDirect3DDevice9_EndScene(device);
7294 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7297 if(i == 0) {
7298 color = getPixelColor(device, 480, 360);
7299 ok(color == 0x00ff0000,
7300 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7301 color = getPixelColor(device, 160, 120);
7302 ok(color == 0x00ffffff,
7303 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7304 color = getPixelColor(device, 160, 360);
7305 ok(color == 0x000000ff || !ub_ok,
7306 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7307 color = getPixelColor(device, 480, 120);
7308 ok(color == 0x000000ff || !ub_ok,
7309 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7310 } else {
7311 color = getPixelColor(device, 480, 360);
7312 ok(color == 0x000000ff,
7313 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7314 color = getPixelColor(device, 160, 120);
7315 ok(color == 0x00ffffff,
7316 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7317 color = getPixelColor(device, 160, 360);
7318 ok(color == 0x00ff0000 || !ub_ok,
7319 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7320 color = getPixelColor(device, 480, 120);
7321 ok(color == 0x00ff0000 || !ub_ok,
7322 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7324 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7327 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7328 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7329 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7330 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7331 IDirect3DVertexBuffer9_Release(vb2);
7333 out:
7334 IDirect3DVertexBuffer9_Release(vb);
7335 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7336 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7337 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7338 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7339 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7340 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7341 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7344 struct vertex_float16color {
7345 float x, y, z;
7346 DWORD c1, c2;
7349 static void test_vshader_float16(IDirect3DDevice9 *device)
7351 HRESULT hr;
7352 DWORD color;
7353 void *data;
7354 static const D3DVERTEXELEMENT9 decl_elements[] = {
7355 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7356 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7357 D3DDECL_END()
7359 IDirect3DVertexDeclaration9 *vdecl = NULL;
7360 IDirect3DVertexBuffer9 *buffer = NULL;
7361 IDirect3DVertexShader9 *shader;
7362 DWORD shader_code[] = {
7363 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7364 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7365 0x90e40001, 0x0000ffff
7367 struct vertex_float16color quad[] = {
7368 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7369 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7370 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7371 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7373 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7374 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7375 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7376 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7378 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7379 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7380 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7381 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7383 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7384 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7385 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7386 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7389 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7390 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7392 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7393 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7394 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7395 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7396 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7397 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7399 hr = IDirect3DDevice9_BeginScene(device);
7400 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7401 if(SUCCEEDED(hr)) {
7402 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7405 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7406 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7407 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7409 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7411 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7413 hr = IDirect3DDevice9_EndScene(device);
7414 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7416 color = getPixelColor(device, 480, 360);
7417 ok(color == 0x00ff0000,
7418 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7419 color = getPixelColor(device, 160, 120);
7420 ok(color == 0x00000000,
7421 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7422 color = getPixelColor(device, 160, 360);
7423 ok(color == 0x0000ff00,
7424 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7425 color = getPixelColor(device, 480, 120);
7426 ok(color == 0x000000ff,
7427 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7428 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7431 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7433 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7434 D3DPOOL_MANAGED, &buffer, NULL);
7435 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7436 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7437 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7438 memcpy(data, quad, sizeof(quad));
7439 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7440 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7441 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7442 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7444 hr = IDirect3DDevice9_BeginScene(device);
7445 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7446 if(SUCCEEDED(hr)) {
7447 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7448 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7449 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7450 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7451 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7452 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7453 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7454 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7456 hr = IDirect3DDevice9_EndScene(device);
7457 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7460 color = getPixelColor(device, 480, 360);
7461 ok(color == 0x00ff0000,
7462 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7463 color = getPixelColor(device, 160, 120);
7464 ok(color == 0x00000000,
7465 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7466 color = getPixelColor(device, 160, 360);
7467 ok(color == 0x0000ff00,
7468 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7469 color = getPixelColor(device, 480, 120);
7470 ok(color == 0x000000ff,
7471 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7472 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7474 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7475 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7476 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7477 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7478 IDirect3DDevice9_SetVertexShader(device, NULL);
7479 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7481 IDirect3DVertexDeclaration9_Release(vdecl);
7482 IDirect3DVertexShader9_Release(shader);
7483 IDirect3DVertexBuffer9_Release(buffer);
7486 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7488 D3DCAPS9 caps;
7489 IDirect3DTexture9 *texture;
7490 HRESULT hr;
7491 D3DLOCKED_RECT rect;
7492 unsigned int x, y;
7493 DWORD *dst, color;
7494 const float quad[] = {
7495 -1.0, -1.0, 0.1, -0.2, -0.2,
7496 1.0, -1.0, 0.1, 1.2, -0.2,
7497 -1.0, 1.0, 0.1, -0.2, 1.2,
7498 1.0, 1.0, 0.1, 1.2, 1.2
7500 memset(&caps, 0, sizeof(caps));
7502 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7503 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7504 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7505 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7506 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7507 "Card has conditional NP2 support without power of two restriction set\n");
7508 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7509 return;
7510 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7511 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7512 return;
7515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7518 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7521 memset(&rect, 0, sizeof(rect));
7522 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7523 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7524 for(y = 0; y < 10; y++) {
7525 for(x = 0; x < 10; x++) {
7526 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7527 if(x == 0 || x == 9 || y == 0 || y == 9) {
7528 *dst = 0x00ff0000;
7529 } else {
7530 *dst = 0x000000ff;
7534 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7535 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7537 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7538 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7539 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7540 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7541 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7542 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7543 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7544 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7546 hr = IDirect3DDevice9_BeginScene(device);
7547 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7548 if(SUCCEEDED(hr)) {
7549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7550 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7552 hr = IDirect3DDevice9_EndScene(device);
7553 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7556 color = getPixelColor(device, 1, 1);
7557 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7558 color = getPixelColor(device, 639, 479);
7559 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7561 color = getPixelColor(device, 135, 101);
7562 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7563 color = getPixelColor(device, 140, 101);
7564 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7565 color = getPixelColor(device, 135, 105);
7566 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7567 color = getPixelColor(device, 140, 105);
7568 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7570 color = getPixelColor(device, 135, 376);
7571 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7572 color = getPixelColor(device, 140, 376);
7573 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7574 color = getPixelColor(device, 135, 379);
7575 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7576 color = getPixelColor(device, 140, 379);
7577 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7579 color = getPixelColor(device, 500, 101);
7580 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7581 color = getPixelColor(device, 504, 101);
7582 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7583 color = getPixelColor(device, 500, 105);
7584 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7585 color = getPixelColor(device, 504, 105);
7586 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7588 color = getPixelColor(device, 500, 376);
7589 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7590 color = getPixelColor(device, 504, 376);
7591 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7592 color = getPixelColor(device, 500, 380);
7593 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7594 color = getPixelColor(device, 504, 380);
7595 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7597 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7599 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7600 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7601 IDirect3DTexture9_Release(texture);
7604 static void vFace_register_test(IDirect3DDevice9 *device)
7606 HRESULT hr;
7607 DWORD color;
7608 const DWORD shader_code[] = {
7609 0xffff0300, /* ps_3_0 */
7610 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7611 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7612 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7613 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7614 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7615 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7616 0x0000ffff /* END */
7618 const DWORD vshader_code[] = {
7619 0xfffe0300, /* vs_3_0 */
7620 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7621 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7622 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7623 0x0000ffff /* end */
7625 IDirect3DPixelShader9 *shader;
7626 IDirect3DVertexShader9 *vshader;
7627 IDirect3DTexture9 *texture;
7628 IDirect3DSurface9 *surface, *backbuffer;
7629 const float quad[] = {
7630 -1.0, -1.0, 0.1,
7631 1.0, -1.0, 0.1,
7632 -1.0, 0.0, 0.1,
7634 1.0, -1.0, 0.1,
7635 1.0, 0.0, 0.1,
7636 -1.0, 0.0, 0.1,
7638 -1.0, 0.0, 0.1,
7639 -1.0, 1.0, 0.1,
7640 1.0, 0.0, 0.1,
7642 1.0, 0.0, 0.1,
7643 -1.0, 1.0, 0.1,
7644 1.0, 1.0, 0.1,
7646 const float blit[] = {
7647 0.0, -1.0, 0.1, 0.0, 0.0,
7648 1.0, -1.0, 0.1, 1.0, 0.0,
7649 0.0, 1.0, 0.1, 0.0, 1.0,
7650 1.0, 1.0, 0.1, 1.0, 1.0,
7653 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7654 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7655 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7656 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7657 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7658 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7659 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7660 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7661 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7662 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7663 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7665 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7666 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7667 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7671 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7673 hr = IDirect3DDevice9_BeginScene(device);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7675 if(SUCCEEDED(hr)) {
7676 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7677 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7682 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7683 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7684 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7685 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7686 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7688 /* Blit the texture onto the back buffer to make it visible */
7689 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7690 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7691 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7692 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7693 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7694 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7695 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7696 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7697 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7699 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7700 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7703 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7705 hr = IDirect3DDevice9_EndScene(device);
7706 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7709 color = getPixelColor(device, 160, 360);
7710 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7711 color = getPixelColor(device, 160, 120);
7712 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7713 color = getPixelColor(device, 480, 360);
7714 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7715 color = getPixelColor(device, 480, 120);
7716 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7717 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7720 IDirect3DDevice9_SetTexture(device, 0, NULL);
7721 IDirect3DPixelShader9_Release(shader);
7722 IDirect3DVertexShader9_Release(vshader);
7723 IDirect3DSurface9_Release(surface);
7724 IDirect3DSurface9_Release(backbuffer);
7725 IDirect3DTexture9_Release(texture);
7728 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7730 HRESULT hr;
7731 DWORD color;
7732 int i;
7733 D3DCAPS9 caps;
7734 BOOL L6V5U5_supported = FALSE;
7735 IDirect3DTexture9 *tex1, *tex2;
7736 D3DLOCKED_RECT locked_rect;
7738 static const float quad[][7] = {
7739 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7740 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7741 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7742 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7745 static const D3DVERTEXELEMENT9 decl_elements[] = {
7746 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7747 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7748 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7749 D3DDECL_END()
7752 /* use asymmetric matrix to test loading */
7753 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7754 float scale, offset;
7756 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7757 IDirect3DTexture9 *texture = NULL;
7759 memset(&caps, 0, sizeof(caps));
7760 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7761 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7762 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7763 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7764 return;
7765 } else {
7766 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7767 * They report that it is not supported, but after that bump mapping works properly. So just test
7768 * if the format is generally supported, and check the BUMPENVMAP flag
7770 IDirect3D9 *d3d9;
7772 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7773 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7774 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7775 L6V5U5_supported = SUCCEEDED(hr);
7776 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7777 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7778 IDirect3D9_Release(d3d9);
7779 if(FAILED(hr)) {
7780 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7781 return;
7785 /* Generate the textures */
7786 generate_bumpmap_textures(device);
7788 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7789 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7790 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7791 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7792 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7793 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7794 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7795 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7797 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7798 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7800 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7802 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7804 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7805 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7809 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7811 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7812 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7815 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7817 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7818 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7821 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7822 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7823 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7824 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7826 hr = IDirect3DDevice9_BeginScene(device);
7827 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7830 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7832 hr = IDirect3DDevice9_EndScene(device);
7833 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7835 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7836 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7837 * But since testing the color match is not the purpose of the test don't be too picky
7839 color = getPixelColor(device, 320-32, 240);
7840 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7841 color = getPixelColor(device, 320+32, 240);
7842 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7843 color = getPixelColor(device, 320, 240-32);
7844 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7845 color = getPixelColor(device, 320, 240+32);
7846 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7847 color = getPixelColor(device, 320, 240);
7848 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7849 color = getPixelColor(device, 320+32, 240+32);
7850 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7851 color = getPixelColor(device, 320-32, 240+32);
7852 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7853 color = getPixelColor(device, 320+32, 240-32);
7854 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7855 color = getPixelColor(device, 320-32, 240-32);
7856 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7857 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7858 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7860 for(i = 0; i < 2; i++) {
7861 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7862 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7863 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7864 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7865 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7866 IDirect3DTexture9_Release(texture); /* To destroy it */
7869 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7870 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7871 goto cleanup;
7873 if(L6V5U5_supported == FALSE) {
7874 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7875 goto cleanup;
7878 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7880 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7881 * would only make this test more complicated
7883 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7884 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7885 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7886 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7888 memset(&locked_rect, 0, sizeof(locked_rect));
7889 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7890 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7891 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7892 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7893 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7895 memset(&locked_rect, 0, sizeof(locked_rect));
7896 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7897 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7898 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7899 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7900 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7902 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7903 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7904 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7905 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7907 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7908 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7909 scale = 2.0;
7910 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7911 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7912 offset = 0.1;
7913 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7914 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7916 hr = IDirect3DDevice9_BeginScene(device);
7917 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7918 if(SUCCEEDED(hr)) {
7919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7920 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7921 hr = IDirect3DDevice9_EndScene(device);
7922 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7925 color = getPixelColor(device, 320, 240);
7926 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7927 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7928 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7930 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7931 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7932 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7934 /* Check a result scale factor > 1.0 */
7935 scale = 10;
7936 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7937 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7938 offset = 10;
7939 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7940 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7942 hr = IDirect3DDevice9_BeginScene(device);
7943 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7944 if(SUCCEEDED(hr)) {
7945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7946 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7947 hr = IDirect3DDevice9_EndScene(device);
7948 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7950 color = getPixelColor(device, 320, 240);
7951 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7952 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7953 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7955 /* Check clamping in the scale factor calculation */
7956 scale = 1000;
7957 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7958 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7959 offset = -1;
7960 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7961 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7963 hr = IDirect3DDevice9_BeginScene(device);
7964 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7965 if(SUCCEEDED(hr)) {
7966 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7967 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7968 hr = IDirect3DDevice9_EndScene(device);
7969 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7971 color = getPixelColor(device, 320, 240);
7972 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7974 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7976 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7977 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7978 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7979 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7981 IDirect3DTexture9_Release(tex1);
7982 IDirect3DTexture9_Release(tex2);
7984 cleanup:
7985 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7986 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7987 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7988 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7990 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7991 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7992 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7995 static void stencil_cull_test(IDirect3DDevice9 *device) {
7996 HRESULT hr;
7997 IDirect3DSurface9 *depthstencil = NULL;
7998 D3DSURFACE_DESC desc;
7999 float quad1[] = {
8000 -1.0, -1.0, 0.1,
8001 0.0, -1.0, 0.1,
8002 -1.0, 0.0, 0.1,
8003 0.0, 0.0, 0.1,
8005 float quad2[] = {
8006 0.0, -1.0, 0.1,
8007 1.0, -1.0, 0.1,
8008 0.0, 0.0, 0.1,
8009 1.0, 0.0, 0.1,
8011 float quad3[] = {
8012 0.0, 0.0, 0.1,
8013 1.0, 0.0, 0.1,
8014 0.0, 1.0, 0.1,
8015 1.0, 1.0, 0.1,
8017 float quad4[] = {
8018 -1.0, 0.0, 0.1,
8019 0.0, 0.0, 0.1,
8020 -1.0, 1.0, 0.1,
8021 0.0, 1.0, 0.1,
8023 struct vertex painter[] = {
8024 {-1.0, -1.0, 0.0, 0x00000000},
8025 { 1.0, -1.0, 0.0, 0x00000000},
8026 {-1.0, 1.0, 0.0, 0x00000000},
8027 { 1.0, 1.0, 0.0, 0x00000000},
8029 WORD indices_cw[] = {0, 1, 3};
8030 WORD indices_ccw[] = {0, 2, 3};
8031 unsigned int i;
8032 DWORD color;
8034 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8035 if(depthstencil == NULL) {
8036 skip("No depth stencil buffer\n");
8037 return;
8039 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8040 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8041 IDirect3DSurface9_Release(depthstencil);
8042 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8043 skip("No 4 or 8 bit stencil surface\n");
8044 return;
8047 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8048 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8049 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8052 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8054 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8055 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8056 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8058 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8061 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8063 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8065 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8068 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8070 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8072 /* First pass: Fill the stencil buffer with some values... */
8073 hr = IDirect3DDevice9_BeginScene(device);
8074 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8075 if(SUCCEEDED(hr))
8077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8080 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8081 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8082 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8083 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8084 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8089 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8090 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8091 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8092 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8093 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8094 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8095 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8098 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8099 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8100 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8101 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8102 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8103 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8104 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8107 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8108 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8109 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8110 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8111 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8112 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8113 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8115 hr = IDirect3DDevice9_EndScene(device);
8116 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8119 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8121 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8123 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8133 /* 2nd pass: Make the stencil values visible */
8134 hr = IDirect3DDevice9_BeginScene(device);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8136 if(SUCCEEDED(hr))
8138 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8139 for(i = 0; i < 16; i++) {
8140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8143 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8144 painter[1].diffuse = (i * 16);
8145 painter[2].diffuse = (i * 16);
8146 painter[3].diffuse = (i * 16);
8147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8148 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8150 hr = IDirect3DDevice9_EndScene(device);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8157 color = getPixelColor(device, 160, 420);
8158 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8159 color = getPixelColor(device, 160, 300);
8160 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8162 color = getPixelColor(device, 480, 420);
8163 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8164 color = getPixelColor(device, 480, 300);
8165 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8167 color = getPixelColor(device, 160, 180);
8168 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8169 color = getPixelColor(device, 160, 60);
8170 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8172 color = getPixelColor(device, 480, 180);
8173 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8174 color = getPixelColor(device, 480, 60);
8175 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8178 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8181 static void vpos_register_test(IDirect3DDevice9 *device)
8183 HRESULT hr;
8184 DWORD color;
8185 const DWORD shader_code[] = {
8186 0xffff0300, /* ps_3_0 */
8187 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8188 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8189 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8190 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8191 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8192 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8193 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8194 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8195 0x0000ffff /* end */
8197 const DWORD shader_frac_code[] = {
8198 0xffff0300, /* ps_3_0 */
8199 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8200 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8201 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8202 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8203 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8204 0x0000ffff /* end */
8206 const DWORD vshader_code[] = {
8207 0xfffe0300, /* vs_3_0 */
8208 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8209 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8210 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8211 0x0000ffff /* end */
8213 IDirect3DVertexShader9 *vshader;
8214 IDirect3DPixelShader9 *shader, *shader_frac;
8215 IDirect3DSurface9 *surface = NULL, *backbuffer;
8216 const float quad[] = {
8217 -1.0, -1.0, 0.1, 0.0, 0.0,
8218 1.0, -1.0, 0.1, 1.0, 0.0,
8219 -1.0, 1.0, 0.1, 0.0, 1.0,
8220 1.0, 1.0, 0.1, 1.0, 1.0,
8222 D3DLOCKED_RECT lr;
8223 float constant[4] = {1.0, 0.0, 320, 240};
8224 DWORD *pos;
8226 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8227 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8228 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8229 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8230 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8231 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8232 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8233 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8234 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8235 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8236 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8238 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8239 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8240 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8241 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8243 hr = IDirect3DDevice9_BeginScene(device);
8244 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8245 if(SUCCEEDED(hr)) {
8246 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8247 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8249 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8250 hr = IDirect3DDevice9_EndScene(device);
8251 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8254 /* This has to be pixel exact */
8255 color = getPixelColor(device, 319, 239);
8256 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8257 color = getPixelColor(device, 320, 239);
8258 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8259 color = getPixelColor(device, 319, 240);
8260 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8261 color = getPixelColor(device, 320, 240);
8262 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8263 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8265 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8266 &surface, NULL);
8267 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8268 hr = IDirect3DDevice9_BeginScene(device);
8269 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8270 if(SUCCEEDED(hr)) {
8271 constant[2] = 16; constant[3] = 16;
8272 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8273 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8274 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8277 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8278 hr = IDirect3DDevice9_EndScene(device);
8279 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8281 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8282 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8284 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8285 color = *pos & 0x00ffffff;
8286 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8287 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8288 color = *pos & 0x00ffffff;
8289 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8290 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8291 color = *pos & 0x00ffffff;
8292 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8293 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8294 color = *pos & 0x00ffffff;
8295 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8297 hr = IDirect3DSurface9_UnlockRect(surface);
8298 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8300 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8301 * have full control over the multisampling setting inside this test
8303 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8304 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8305 hr = IDirect3DDevice9_BeginScene(device);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8307 if(SUCCEEDED(hr)) {
8308 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8311 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8312 hr = IDirect3DDevice9_EndScene(device);
8313 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8315 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8316 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8318 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8319 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8321 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8322 color = *pos & 0x00ffffff;
8323 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8325 hr = IDirect3DSurface9_UnlockRect(surface);
8326 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8328 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8329 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8330 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8331 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8332 IDirect3DPixelShader9_Release(shader);
8333 IDirect3DPixelShader9_Release(shader_frac);
8334 IDirect3DVertexShader9_Release(vshader);
8335 if(surface) IDirect3DSurface9_Release(surface);
8336 IDirect3DSurface9_Release(backbuffer);
8339 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8341 D3DCOLOR color;
8343 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8344 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8345 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8346 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8347 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8349 ++r;
8350 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8351 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8352 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8353 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8354 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8356 return TRUE;
8359 static void pointsize_test(IDirect3DDevice9 *device)
8361 HRESULT hr;
8362 D3DCAPS9 caps;
8363 D3DMATRIX matrix;
8364 D3DMATRIX identity;
8365 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8366 DWORD color;
8367 IDirect3DSurface9 *rt, *backbuffer;
8368 IDirect3DTexture9 *tex1, *tex2;
8369 RECT rect = {0, 0, 128, 128};
8370 D3DLOCKED_RECT lr;
8371 const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8372 0x00000000, 0x00000000};
8373 const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8374 0x00000000, 0x0000ff00};
8376 const float vertices[] = {
8377 64, 64, 0.1,
8378 128, 64, 0.1,
8379 192, 64, 0.1,
8380 256, 64, 0.1,
8381 320, 64, 0.1,
8382 384, 64, 0.1,
8383 448, 64, 0.1,
8384 512, 64, 0.1,
8387 /* 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 */
8388 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;
8389 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;
8390 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;
8391 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;
8393 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;
8394 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;
8395 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;
8396 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;
8398 memset(&caps, 0, sizeof(caps));
8399 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8400 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8401 if(caps.MaxPointSize < 32.0) {
8402 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8403 return;
8406 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8407 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8408 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8410 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8411 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8412 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8413 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8415 hr = IDirect3DDevice9_BeginScene(device);
8416 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8417 if (SUCCEEDED(hr))
8419 ptsize = 15.0;
8420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8421 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8423 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8425 ptsize = 31.0;
8426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8429 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8431 ptsize = 30.75;
8432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8433 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8435 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8437 if (caps.MaxPointSize >= 63.0)
8439 ptsize = 63.0;
8440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8442 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8443 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8445 ptsize = 62.75;
8446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8447 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8448 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8449 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8452 ptsize = 1.0;
8453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8454 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8456 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8458 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8459 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8460 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8461 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8463 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8464 ptsize = 15.0;
8465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8466 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8467 ptsize = 1.0;
8468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8469 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8471 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8474 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8476 /* pointsize < pointsize_min < pointsize_max?
8477 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8478 ptsize = 1.0;
8479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8481 ptsize = 15.0;
8482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8483 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8485 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8488 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8490 hr = IDirect3DDevice9_EndScene(device);
8491 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8494 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8495 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8496 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8498 if (caps.MaxPointSize >= 63.0)
8500 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8501 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8504 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8505 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8506 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8507 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8508 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8510 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8512 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8513 * generates texture coordinates for the point(result: Yes, it does)
8515 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8516 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8517 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8519 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8520 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8522 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8523 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8524 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8525 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8526 memset(&lr, 0, sizeof(lr));
8527 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8528 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8529 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8530 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8531 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8532 memset(&lr, 0, sizeof(lr));
8533 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8534 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8535 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8536 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8537 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8538 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8539 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8540 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8541 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8542 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8543 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8544 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8545 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8546 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8547 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8548 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8550 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8551 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8554 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8555 ptsize = 32.0;
8556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8559 hr = IDirect3DDevice9_BeginScene(device);
8560 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8561 if(SUCCEEDED(hr))
8563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8564 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8565 hr = IDirect3DDevice9_EndScene(device);
8566 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8569 color = getPixelColor(device, 64-4, 64-4);
8570 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8571 color = getPixelColor(device, 64-4, 64+4);
8572 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8573 color = getPixelColor(device, 64+4, 64+4);
8574 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8575 color = getPixelColor(device, 64+4, 64-4);
8576 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8577 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8579 U(matrix).m[0][0] = 1.0f / 64.0f;
8580 U(matrix).m[1][1] = -1.0f / 64.0f;
8581 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8582 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8584 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8585 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8587 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8588 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8589 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8591 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8592 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8593 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8594 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8596 hr = IDirect3DDevice9_BeginScene(device);
8597 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8598 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8599 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8600 hr = IDirect3DDevice9_EndScene(device);
8601 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8603 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8604 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8605 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8606 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8607 IDirect3DSurface9_Release(backbuffer);
8608 IDirect3DSurface9_Release(rt);
8610 color = getPixelColor(device, 64-4, 64-4);
8611 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8612 "Expected color 0x00ff0000, got 0x%08x.\n", color);
8613 color = getPixelColor(device, 64+4, 64-4);
8614 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8615 "Expected color 0x00ffff00, got 0x%08x.\n", color);
8616 color = getPixelColor(device, 64-4, 64+4);
8617 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8618 "Expected color 0x00000000, got 0x%08x.\n", color);
8619 color = getPixelColor(device, 64+4, 64+4);
8620 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8621 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8624 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8626 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8627 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8628 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8629 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8630 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8631 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8632 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8633 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8634 IDirect3DTexture9_Release(tex1);
8635 IDirect3DTexture9_Release(tex2);
8637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8638 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8640 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8641 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8642 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8645 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8647 static const DWORD vshader_code[] =
8649 0xfffe0300, /* vs_3_0 */
8650 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8651 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8652 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8653 0x0000ffff /* end */
8655 static const DWORD pshader_code1[] =
8657 0xffff0300, /* ps_3_0 */
8658 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8659 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8660 0x0000ffff /* end */
8662 static const DWORD pshader_code2[] =
8664 0xffff0300, /* ps_3_0 */
8665 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8666 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8667 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8668 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8669 0x0000ffff /* end */
8672 HRESULT hr;
8673 IDirect3DVertexShader9 *vs;
8674 IDirect3DPixelShader9 *ps1, *ps2;
8675 IDirect3DTexture9 *tex1, *tex2;
8676 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8677 D3DCAPS9 caps;
8678 DWORD color;
8679 UINT i, j;
8680 float quad[] = {
8681 -1.0, -1.0, 0.1,
8682 1.0, -1.0, 0.1,
8683 -1.0, 1.0, 0.1,
8684 1.0, 1.0, 0.1,
8686 float texquad[] = {
8687 -1.0, -1.0, 0.1, 0.0, 0.0,
8688 0.0, -1.0, 0.1, 1.0, 0.0,
8689 -1.0, 1.0, 0.1, 0.0, 1.0,
8690 0.0, 1.0, 0.1, 1.0, 1.0,
8692 0.0, -1.0, 0.1, 0.0, 0.0,
8693 1.0, -1.0, 0.1, 1.0, 0.0,
8694 0.0, 1.0, 0.1, 0.0, 1.0,
8695 1.0, 1.0, 0.1, 1.0, 1.0,
8698 memset(&caps, 0, sizeof(caps));
8699 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8700 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8701 if(caps.NumSimultaneousRTs < 2) {
8702 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8703 return;
8706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8707 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8709 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8710 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8711 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8713 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8714 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8715 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8716 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8717 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8718 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8719 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8720 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8721 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
8722 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8723 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
8724 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
8726 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8727 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8728 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8729 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8730 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8731 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8733 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8734 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8735 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8736 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8737 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8738 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8739 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8740 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8742 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8743 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8744 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8745 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8746 color = getPixelColorFromSurface(readback, 8, 8);
8747 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8748 "Expected color 0x000000ff, got 0x%08x.\n", color);
8749 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8750 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8751 color = getPixelColorFromSurface(readback, 8, 8);
8752 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8753 "Expected color 0x000000ff, got 0x%08x.\n", color);
8755 /* Render targets not written by the pixel shader should be unmodified. */
8756 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
8757 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8758 hr = IDirect3DDevice9_BeginScene(device);
8759 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8761 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8762 hr = IDirect3DDevice9_EndScene(device);
8763 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8764 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8765 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8766 color = getPixelColorFromSurface(readback, 8, 8);
8767 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8768 "Expected color 0xff00ff00, got 0x%08x.\n", color);
8769 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8770 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8771 for (i = 6; i < 10; ++i)
8773 for (j = 6; j < 10; ++j)
8775 color = getPixelColorFromSurface(readback, j, i);
8776 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8777 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
8781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8782 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8783 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8784 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8785 color = getPixelColorFromSurface(readback, 8, 8);
8786 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8787 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8788 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8789 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8790 color = getPixelColorFromSurface(readback, 8, 8);
8791 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8792 "Expected color 0x0000ff00, got 0x%08x.\n", color);
8794 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
8795 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8797 hr = IDirect3DDevice9_BeginScene(device);
8798 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8799 if(SUCCEEDED(hr)) {
8800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8801 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8803 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8804 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8805 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8806 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8807 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8808 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8809 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8810 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8811 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8812 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8814 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8817 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8819 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8820 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8822 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8824 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8825 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8827 hr = IDirect3DDevice9_EndScene(device);
8828 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8831 color = getPixelColor(device, 160, 240);
8832 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8833 color = getPixelColor(device, 480, 240);
8834 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8835 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8837 IDirect3DPixelShader9_Release(ps2);
8838 IDirect3DPixelShader9_Release(ps1);
8839 IDirect3DVertexShader9_Release(vs);
8840 IDirect3DTexture9_Release(tex1);
8841 IDirect3DTexture9_Release(tex2);
8842 IDirect3DSurface9_Release(surf1);
8843 IDirect3DSurface9_Release(surf2);
8844 IDirect3DSurface9_Release(backbuf);
8845 IDirect3DSurface9_Release(readback);
8848 struct formats {
8849 const char *fmtName;
8850 D3DFORMAT textureFormat;
8851 DWORD resultColorBlending;
8852 DWORD resultColorNoBlending;
8855 static const struct formats test_formats[] = {
8856 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8857 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8858 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8859 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8860 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8861 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8862 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8863 { NULL, 0 }
8866 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8868 HRESULT hr;
8869 IDirect3DTexture9 *offscreenTexture = NULL;
8870 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8871 IDirect3D9 *d3d = NULL;
8872 DWORD color;
8873 DWORD r0, g0, b0, r1, g1, b1;
8874 int fmt_index;
8876 static const float quad[][5] = {
8877 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8878 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8879 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8880 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8883 /* Quad with R=0x10, G=0x20 */
8884 static const struct vertex quad1[] = {
8885 {-1.0f, -1.0f, 0.1f, 0x80102000},
8886 {-1.0f, 1.0f, 0.1f, 0x80102000},
8887 { 1.0f, -1.0f, 0.1f, 0x80102000},
8888 { 1.0f, 1.0f, 0.1f, 0x80102000},
8891 /* Quad with R=0x20, G=0x10 */
8892 static const struct vertex quad2[] = {
8893 {-1.0f, -1.0f, 0.1f, 0x80201000},
8894 {-1.0f, 1.0f, 0.1f, 0x80201000},
8895 { 1.0f, -1.0f, 0.1f, 0x80201000},
8896 { 1.0f, 1.0f, 0.1f, 0x80201000},
8899 IDirect3DDevice9_GetDirect3D(device, &d3d);
8901 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8902 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8903 if(!backbuffer) {
8904 goto out;
8907 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8909 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8911 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8912 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
8914 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
8915 continue;
8918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8919 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8921 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8922 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8923 if(!offscreenTexture) {
8924 continue;
8927 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8928 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8929 if(!offscreen) {
8930 continue;
8933 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8934 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8936 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8937 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8938 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8939 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8940 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8941 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8942 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8943 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8945 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8947 /* Below we will draw two quads with different colors and try to blend them together.
8948 * The result color is compared with the expected outcome.
8950 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8951 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8952 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8953 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8954 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8957 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8959 /* Draw a quad using color 0x0010200 */
8960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8961 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8963 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8965 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8967 /* Draw a quad using color 0x0020100 */
8968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8971 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8973 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8975 /* We don't want to blend the result on the backbuffer */
8976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8977 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8979 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8980 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8981 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8982 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8983 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8985 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8986 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8988 /* This time with the texture */
8989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8990 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8992 IDirect3DDevice9_EndScene(device);
8995 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8996 /* Compare the color of the center quad with our expectation */
8997 color = getPixelColor(device, 320, 240);
8998 r0 = (color & 0x00ff0000) >> 16;
8999 g0 = (color & 0x0000ff00) >> 8;
9000 b0 = (color & 0x000000ff) >> 0;
9002 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9003 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
9004 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
9006 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9007 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9008 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9009 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9010 } else {
9011 /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9012 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9013 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9014 color = getPixelColor(device, 320, 240);
9015 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
9017 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9019 IDirect3DDevice9_SetTexture(device, 0, NULL);
9020 if(offscreenTexture) {
9021 IDirect3DTexture9_Release(offscreenTexture);
9023 if(offscreen) {
9024 IDirect3DSurface9_Release(offscreen);
9028 out:
9029 /* restore things */
9030 if(backbuffer) {
9031 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9032 IDirect3DSurface9_Release(backbuffer);
9036 static void tssargtemp_test(IDirect3DDevice9 *device)
9038 HRESULT hr;
9039 DWORD color;
9040 static const struct vertex quad[] = {
9041 {-1.0, -1.0, 0.1, 0x00ff0000},
9042 { 1.0, -1.0, 0.1, 0x00ff0000},
9043 {-1.0, 1.0, 0.1, 0x00ff0000},
9044 { 1.0, 1.0, 0.1, 0x00ff0000}
9046 D3DCAPS9 caps;
9048 memset(&caps, 0, sizeof(caps));
9049 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9050 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9051 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9052 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9053 return;
9056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9057 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9059 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9060 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9061 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9062 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9064 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9065 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9067 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9069 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9071 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9072 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9073 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9074 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9075 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9076 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9078 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9079 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9082 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9083 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9084 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9086 hr = IDirect3DDevice9_BeginScene(device);
9087 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9088 if(SUCCEEDED(hr)) {
9089 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9090 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9091 hr = IDirect3DDevice9_EndScene(device);
9092 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9094 color = getPixelColor(device, 320, 240);
9095 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9096 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9098 /* Set stage 1 back to default */
9099 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9100 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9101 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9102 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9103 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9104 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9105 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9106 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9107 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9108 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9111 struct testdata
9113 DWORD idxVertex; /* number of instances in the first stream */
9114 DWORD idxColor; /* number of instances in the second stream */
9115 DWORD idxInstance; /* should be 1 ?? */
9116 DWORD color1; /* color 1 instance */
9117 DWORD color2; /* color 2 instance */
9118 DWORD color3; /* color 3 instance */
9119 DWORD color4; /* color 4 instance */
9120 WORD strVertex; /* specify which stream to use 0-2*/
9121 WORD strColor;
9122 WORD strInstance;
9125 static const struct testdata testcases[]=
9127 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
9128 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
9129 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
9130 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
9131 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
9132 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
9133 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
9134 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
9135 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
9136 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
9137 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
9138 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
9139 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
9140 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
9142 This draws one instance on some machines, no instance on others
9143 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2},
9146 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
9147 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9151 /* Drawing Indexed Geometry with instances*/
9152 static void stream_test(IDirect3DDevice9 *device)
9154 IDirect3DVertexBuffer9 *vb = NULL;
9155 IDirect3DVertexBuffer9 *vb2 = NULL;
9156 IDirect3DVertexBuffer9 *vb3 = NULL;
9157 IDirect3DIndexBuffer9 *ib = NULL;
9158 IDirect3DVertexDeclaration9 *pDecl = NULL;
9159 IDirect3DVertexShader9 *shader = NULL;
9160 HRESULT hr;
9161 BYTE *data;
9162 DWORD color;
9163 DWORD ind;
9164 unsigned i;
9166 const DWORD shader_code[] =
9168 0xfffe0101, /* vs_1_1 */
9169 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9170 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9171 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
9172 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9173 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9174 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9175 0x0000ffff
9178 const float quad[][3] =
9180 {-0.5f, -0.5f, 1.1f}, /*0 */
9181 {-0.5f, 0.5f, 1.1f}, /*1 */
9182 { 0.5f, -0.5f, 1.1f}, /*2 */
9183 { 0.5f, 0.5f, 1.1f}, /*3 */
9186 const float vertcolor[][4] =
9188 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9189 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9190 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9191 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9194 /* 4 position for 4 instances */
9195 const float instancepos[][3] =
9197 {-0.6f,-0.6f, 0.0f},
9198 { 0.6f,-0.6f, 0.0f},
9199 { 0.6f, 0.6f, 0.0f},
9200 {-0.6f, 0.6f, 0.0f},
9203 short indices[] = {0, 1, 2, 1, 2, 3};
9205 D3DVERTEXELEMENT9 decl[] =
9207 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9208 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9209 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9210 D3DDECL_END()
9213 /* set the default value because it isn't done in wine? */
9214 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9215 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9217 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9218 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9219 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9221 /* check wrong cases */
9222 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9223 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9224 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9225 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9226 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9227 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9228 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9229 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9230 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9231 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9232 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9233 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9234 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9235 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9236 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9237 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9238 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9239 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9240 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9241 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9243 /* set the default value back */
9244 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9245 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9247 /* create all VertexBuffers*/
9248 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9249 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9250 if(!vb) {
9251 skip("Failed to create a vertex buffer\n");
9252 return;
9254 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9255 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9256 if(!vb2) {
9257 skip("Failed to create a vertex buffer\n");
9258 goto out;
9260 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9261 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9262 if(!vb3) {
9263 skip("Failed to create a vertex buffer\n");
9264 goto out;
9267 /* create IndexBuffer*/
9268 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9269 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9270 if(!ib) {
9271 skip("Failed to create a index buffer\n");
9272 goto out;
9275 /* copy all Buffers (Vertex + Index)*/
9276 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9277 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9278 memcpy(data, quad, sizeof(quad));
9279 hr = IDirect3DVertexBuffer9_Unlock(vb);
9280 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9281 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9282 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9283 memcpy(data, vertcolor, sizeof(vertcolor));
9284 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9285 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9286 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9287 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9288 memcpy(data, instancepos, sizeof(instancepos));
9289 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9290 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9291 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9292 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9293 memcpy(data, indices, sizeof(indices));
9294 hr = IDirect3DIndexBuffer9_Unlock(ib);
9295 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9297 /* create VertexShader */
9298 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9299 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9300 if(!shader) {
9301 skip("Failed to create a vetex shader\n");
9302 goto out;
9305 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9306 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9308 hr = IDirect3DDevice9_SetIndices(device, ib);
9309 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9311 /* run all tests */
9312 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9314 struct testdata act = testcases[i];
9315 decl[0].Stream = act.strVertex;
9316 decl[1].Stream = act.strColor;
9317 decl[2].Stream = act.strInstance;
9318 /* create VertexDeclarations */
9319 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9320 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9322 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9323 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9325 hr = IDirect3DDevice9_BeginScene(device);
9326 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9327 if(SUCCEEDED(hr))
9329 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9330 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9332 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9333 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9334 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9335 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9337 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9338 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9339 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9340 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9342 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9343 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9344 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9345 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9347 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9348 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9349 hr = IDirect3DDevice9_EndScene(device);
9350 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9352 /* set all StreamSource && StreamSourceFreq back to default */
9353 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9354 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9355 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9356 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9357 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9358 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9359 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9360 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9361 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9362 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9363 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9364 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9367 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9368 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9370 color = getPixelColor(device, 160, 360);
9371 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9372 color = getPixelColor(device, 480, 360);
9373 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9374 color = getPixelColor(device, 480, 120);
9375 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9376 color = getPixelColor(device, 160, 120);
9377 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9379 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9380 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9383 hr = IDirect3DDevice9_SetIndices(device, NULL);
9384 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9386 out:
9387 if(vb) IDirect3DVertexBuffer9_Release(vb);
9388 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9389 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9390 if(ib)IDirect3DIndexBuffer9_Release(ib);
9391 if(shader)IDirect3DVertexShader9_Release(shader);
9394 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9395 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9396 IDirect3DTexture9 *dsttex = NULL;
9397 HRESULT hr;
9398 DWORD color;
9399 D3DRECT r1 = {0, 0, 50, 50 };
9400 D3DRECT r2 = {50, 0, 100, 50 };
9401 D3DRECT r3 = {50, 50, 100, 100};
9402 D3DRECT r4 = {0, 50, 50, 100};
9403 const float quad[] = {
9404 -1.0, -1.0, 0.1, 0.0, 0.0,
9405 1.0, -1.0, 0.1, 1.0, 0.0,
9406 -1.0, 1.0, 0.1, 0.0, 1.0,
9407 1.0, 1.0, 0.1, 1.0, 1.0,
9410 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9411 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9413 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9414 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9415 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9416 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9418 if(!src || !dsttex) {
9419 skip("One or more test resources could not be created\n");
9420 goto cleanup;
9423 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9424 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9427 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9429 /* Clear the StretchRect destination for debugging */
9430 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9431 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9432 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9433 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9435 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9436 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9438 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9439 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9440 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9441 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9442 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9443 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9444 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9445 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9447 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9448 * the target -> texture GL blit path
9450 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9451 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9452 IDirect3DSurface9_Release(dst);
9454 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9455 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9457 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9458 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9459 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9460 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9461 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9462 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9463 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9464 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
9466 hr = IDirect3DDevice9_BeginScene(device);
9467 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9468 if(SUCCEEDED(hr)) {
9469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9470 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9471 hr = IDirect3DDevice9_EndScene(device);
9472 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9475 color = getPixelColor(device, 160, 360);
9476 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9477 color = getPixelColor(device, 480, 360);
9478 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9479 color = getPixelColor(device, 480, 120);
9480 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9481 color = getPixelColor(device, 160, 120);
9482 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9483 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9484 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9486 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9487 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9488 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9489 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9491 cleanup:
9492 if(src) IDirect3DSurface9_Release(src);
9493 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9494 if(dsttex) IDirect3DTexture9_Release(dsttex);
9497 static void texop_test(IDirect3DDevice9 *device)
9499 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9500 IDirect3DTexture9 *texture = NULL;
9501 D3DLOCKED_RECT locked_rect;
9502 D3DCOLOR color;
9503 D3DCAPS9 caps;
9504 HRESULT hr;
9505 unsigned i;
9507 static const struct {
9508 float x, y, z;
9509 float s, t;
9510 D3DCOLOR diffuse;
9511 } quad[] = {
9512 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9513 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9514 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9515 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9518 static const D3DVERTEXELEMENT9 decl_elements[] = {
9519 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9520 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9521 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9522 D3DDECL_END()
9525 static const struct {
9526 D3DTEXTUREOP op;
9527 const char *name;
9528 DWORD caps_flag;
9529 D3DCOLOR result;
9530 } test_data[] = {
9531 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9532 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9533 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9534 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9535 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9536 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9537 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9538 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9539 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9540 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9541 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9542 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9543 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9544 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9545 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9546 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9547 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9548 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9549 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9550 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9551 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9552 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9553 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9556 memset(&caps, 0, sizeof(caps));
9557 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9558 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9560 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9561 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9562 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9563 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9565 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9566 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9567 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9568 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9569 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9570 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9571 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9572 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9573 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9575 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9576 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9577 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9578 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9579 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9580 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9582 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9583 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9586 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9587 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9588 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9589 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9590 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9592 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9593 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9595 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9597 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9599 skip("tex operation %s not supported\n", test_data[i].name);
9600 continue;
9603 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9604 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9606 hr = IDirect3DDevice9_BeginScene(device);
9607 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9610 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9612 hr = IDirect3DDevice9_EndScene(device);
9613 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9615 color = getPixelColor(device, 320, 240);
9616 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9617 test_data[i].name, color, test_data[i].result);
9619 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9620 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9623 if (texture) IDirect3DTexture9_Release(texture);
9624 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9627 static void yuv_color_test(IDirect3DDevice9 *device) {
9628 HRESULT hr;
9629 IDirect3DSurface9 *surface = NULL, *target = NULL;
9630 unsigned int fmt, i;
9631 D3DFORMAT format;
9632 const char *fmt_string;
9633 D3DLOCKED_RECT lr;
9634 IDirect3D9 *d3d;
9635 HRESULT color;
9636 DWORD ref_color_left, ref_color_right;
9638 struct {
9639 DWORD in; /* The input color */
9640 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9641 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9642 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9643 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9644 } test_data[] = {
9645 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9646 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9647 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9648 * that
9650 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9651 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9652 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9653 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9654 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9655 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9656 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9657 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9658 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9659 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9660 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9661 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9662 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9663 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9665 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9666 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9667 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9668 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9671 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9673 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9674 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9676 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9677 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9679 for(fmt = 0; fmt < 2; fmt++) {
9680 if(fmt == 0) {
9681 format = D3DFMT_UYVY;
9682 fmt_string = "D3DFMT_UYVY";
9683 } else {
9684 format = D3DFMT_YUY2;
9685 fmt_string = "D3DFMT_YUY2";
9688 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9689 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9691 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9692 D3DRTYPE_SURFACE, format) != D3D_OK) {
9693 skip("%s is not supported\n", fmt_string);
9694 continue;
9697 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9698 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9701 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9702 if(fmt == 0) {
9703 ref_color_left = test_data[i].uyvy_left;
9704 ref_color_right = test_data[i].uyvy_right;
9705 } else {
9706 ref_color_left = test_data[i].yuy2_left;
9707 ref_color_right = test_data[i].yuy2_right;
9710 memset(&lr, 0, sizeof(lr));
9711 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9712 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9713 *((DWORD *) lr.pBits) = test_data[i].in;
9714 hr = IDirect3DSurface9_UnlockRect(surface);
9715 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9717 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9718 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9719 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9720 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9722 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9723 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9724 * want to add tests for the filtered pixels as well.
9726 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9727 * differently, so we need a max diff of 16
9729 color = getPixelColor(device, 40, 240);
9731 /* Newer versions of the Nvidia Windows driver mix up the U and V channels, breaking all the tests
9732 * where U != V. Skip the entire test if this bug in this case
9734 if (broken(test_data[i].in == 0xff000000 && color == 0x00008800 && format == D3DFMT_UYVY))
9736 skip("Nvidia channel confusion bug detected, skipping YUV tests\n");
9737 IDirect3DSurface9_Release(surface);
9738 goto out;
9741 ok(color_match(color, ref_color_left, 18),
9742 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9743 test_data[i].in, color, ref_color_left, fmt_string);
9744 color = getPixelColor(device, 600, 240);
9745 ok(color_match(color, ref_color_right, 18),
9746 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9747 test_data[i].in, color, ref_color_right, fmt_string);
9748 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9749 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9751 IDirect3DSurface9_Release(surface);
9754 out:
9755 IDirect3DSurface9_Release(target);
9756 IDirect3D9_Release(d3d);
9759 static void texop_range_test(IDirect3DDevice9 *device)
9761 static const struct {
9762 float x, y, z;
9763 D3DCOLOR diffuse;
9764 } quad[] = {
9765 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9766 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9767 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9768 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9770 HRESULT hr;
9771 IDirect3DTexture9 *texture;
9772 D3DLOCKED_RECT locked_rect;
9773 D3DCAPS9 caps;
9774 DWORD color;
9776 /* We need ADD and SUBTRACT operations */
9777 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9778 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9779 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9780 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9781 return;
9783 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9784 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9785 return;
9788 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9789 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9790 /* Stage 1: result = diffuse(=1.0) + diffuse
9791 * stage 2: result = result - tfactor(= 0.5)
9793 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9794 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9795 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9796 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9797 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9798 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9800 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9801 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9802 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9803 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9804 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9805 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9806 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9808 hr = IDirect3DDevice9_BeginScene(device);
9809 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9810 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9811 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9812 hr = IDirect3DDevice9_EndScene(device);
9813 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9815 color = getPixelColor(device, 320, 240);
9816 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9817 color);
9818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9819 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9821 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9822 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9823 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9824 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9825 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9826 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9827 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9828 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9829 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9831 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9832 * stage 2: result = result + diffuse(1.0)
9834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9835 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9837 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9838 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9839 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9840 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9841 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9842 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9843 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9844 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9845 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9846 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9847 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9849 hr = IDirect3DDevice9_BeginScene(device);
9850 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9852 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9853 hr = IDirect3DDevice9_EndScene(device);
9854 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9856 color = getPixelColor(device, 320, 240);
9857 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9858 color);
9859 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9860 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9862 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9863 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9864 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9865 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9866 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9867 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9868 IDirect3DTexture9_Release(texture);
9871 static void alphareplicate_test(IDirect3DDevice9 *device) {
9872 struct vertex quad[] = {
9873 { -1.0, -1.0, 0.1, 0x80ff00ff },
9874 { 1.0, -1.0, 0.1, 0x80ff00ff },
9875 { -1.0, 1.0, 0.1, 0x80ff00ff },
9876 { 1.0, 1.0, 0.1, 0x80ff00ff },
9878 HRESULT hr;
9879 DWORD color;
9881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9882 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9884 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9885 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9887 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9888 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9889 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9890 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9892 hr = IDirect3DDevice9_BeginScene(device);
9893 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9894 if(SUCCEEDED(hr)) {
9895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9896 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9897 hr = IDirect3DDevice9_EndScene(device);
9898 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9901 color = getPixelColor(device, 320, 240);
9902 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9903 color);
9904 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9905 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9907 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9908 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9912 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9913 HRESULT hr;
9914 D3DCAPS9 caps;
9915 DWORD color;
9916 struct vertex quad[] = {
9917 { -1.0, -1.0, 0.1, 0x408080c0 },
9918 { 1.0, -1.0, 0.1, 0x408080c0 },
9919 { -1.0, 1.0, 0.1, 0x408080c0 },
9920 { 1.0, 1.0, 0.1, 0x408080c0 },
9923 memset(&caps, 0, sizeof(caps));
9924 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9925 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9926 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9927 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9928 return;
9931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9932 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9934 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9935 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9937 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9938 * mov r0.a, diffuse.a
9939 * mov r0, r0.a
9941 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9942 * 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
9943 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9945 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9946 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9947 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9948 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9949 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9950 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9951 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9952 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9954 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9955 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9956 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9957 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9958 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9959 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9960 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9962 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9964 hr = IDirect3DDevice9_BeginScene(device);
9965 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9966 if(SUCCEEDED(hr)) {
9967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9968 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9969 hr = IDirect3DDevice9_EndScene(device);
9970 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9973 color = getPixelColor(device, 320, 240);
9974 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9975 color);
9976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9977 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9979 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9980 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9981 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9982 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9983 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9984 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9987 static void zwriteenable_test(IDirect3DDevice9 *device) {
9988 HRESULT hr;
9989 DWORD color;
9990 struct vertex quad1[] = {
9991 { -1.0, -1.0, 0.1, 0x00ff0000},
9992 { -1.0, 1.0, 0.1, 0x00ff0000},
9993 { 1.0, -1.0, 0.1, 0x00ff0000},
9994 { 1.0, 1.0, 0.1, 0x00ff0000},
9996 struct vertex quad2[] = {
9997 { -1.0, -1.0, 0.9, 0x0000ff00},
9998 { -1.0, 1.0, 0.9, 0x0000ff00},
9999 { 1.0, -1.0, 0.9, 0x0000ff00},
10000 { 1.0, 1.0, 0.9, 0x0000ff00},
10003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10006 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10007 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10009 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10011 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10013 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10015 hr = IDirect3DDevice9_BeginScene(device);
10016 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10017 if(SUCCEEDED(hr)) {
10018 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10019 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10020 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10021 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10022 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10023 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
10025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10026 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10028 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10030 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10032 hr = IDirect3DDevice9_EndScene(device);
10033 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10036 color = getPixelColor(device, 320, 240);
10037 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10038 color);
10039 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10040 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10043 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10046 static void alphatest_test(IDirect3DDevice9 *device) {
10047 #define ALPHATEST_PASSED 0x0000ff00
10048 #define ALPHATEST_FAILED 0x00ff0000
10049 struct {
10050 D3DCMPFUNC func;
10051 DWORD color_less;
10052 DWORD color_equal;
10053 DWORD color_greater;
10054 } testdata[] = {
10055 { D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10056 { D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10057 { D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10058 { D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10059 { D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10060 { D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10061 { D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10062 { D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10064 unsigned int i, j;
10065 HRESULT hr;
10066 DWORD color;
10067 struct vertex quad[] = {
10068 { -1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10069 { 1.0, -1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10070 { -1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10071 { 1.0, 1.0, 0.1, ALPHATEST_PASSED | 0x80000000 },
10073 D3DCAPS9 caps;
10075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10077 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10078 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10080 for(j = 0; j < 2; j++) {
10081 if(j == 1) {
10082 /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10083 * the alpha test either for performance reasons(floating point RTs) or to work
10084 * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10085 * codepath for ffp and shader in this case, and the test should cover both
10087 IDirect3DPixelShader9 *ps;
10088 DWORD shader_code[] = {
10089 0xffff0101, /* ps_1_1 */
10090 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10091 0x0000ffff /* end */
10093 memset(&caps, 0, sizeof(caps));
10094 IDirect3DDevice9_GetDeviceCaps(device, &caps);
10095 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10096 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10097 break;
10100 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10101 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10102 IDirect3DDevice9_SetPixelShader(device, ps);
10103 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10104 IDirect3DPixelShader9_Release(ps);
10107 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10109 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10111 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10112 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10114 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10115 hr = IDirect3DDevice9_BeginScene(device);
10116 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10117 if(SUCCEEDED(hr)) {
10118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10119 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10120 hr = IDirect3DDevice9_EndScene(device);
10121 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10123 color = getPixelColor(device, 320, 240);
10124 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10125 color, testdata[i].color_less, testdata[i].func);
10126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10127 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10130 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10132 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10133 hr = IDirect3DDevice9_BeginScene(device);
10134 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10135 if(SUCCEEDED(hr)) {
10136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10137 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10138 hr = IDirect3DDevice9_EndScene(device);
10139 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10141 color = getPixelColor(device, 320, 240);
10142 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10143 color, testdata[i].color_equal, testdata[i].func);
10144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10145 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10148 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10151 hr = IDirect3DDevice9_BeginScene(device);
10152 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10153 if(SUCCEEDED(hr)) {
10154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10155 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10156 hr = IDirect3DDevice9_EndScene(device);
10157 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10159 color = getPixelColor(device, 320, 240);
10160 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10161 color, testdata[i].color_greater, testdata[i].func);
10162 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10163 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10168 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10169 IDirect3DDevice9_SetPixelShader(device, NULL);
10170 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10173 static void sincos_test(IDirect3DDevice9 *device) {
10174 const DWORD sin_shader_code[] = {
10175 0xfffe0200, /* vs_2_0 */
10176 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10177 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10178 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10179 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
10180 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10181 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
10182 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
10183 0x0000ffff /* end */
10185 const DWORD cos_shader_code[] = {
10186 0xfffe0200, /* vs_2_0 */
10187 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10188 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
10189 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
10190 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
10191 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
10192 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
10193 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
10194 0x0000ffff /* end */
10196 IDirect3DVertexShader9 *sin_shader, *cos_shader;
10197 HRESULT hr;
10198 struct {
10199 float x, y, z;
10200 } data[1280];
10201 unsigned int i;
10202 float sincosc1[4] = {D3DSINCOSCONST1};
10203 float sincosc2[4] = {D3DSINCOSCONST2};
10205 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10206 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10208 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10209 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10210 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10211 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10212 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10213 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10214 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10216 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10217 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10219 /* Generate a point from -1 to 1 every 0.5 pixels */
10220 for(i = 0; i < 1280; i++) {
10221 data[i].x = (-640.0 + i) / 640.0;
10222 data[i].y = 0.0;
10223 data[i].z = 0.1;
10226 hr = IDirect3DDevice9_BeginScene(device);
10227 if(SUCCEEDED(hr)) {
10228 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10229 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10231 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10233 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10234 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10236 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10238 hr = IDirect3DDevice9_EndScene(device);
10239 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10241 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10242 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10243 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10245 IDirect3DDevice9_SetVertexShader(device, NULL);
10246 IDirect3DVertexShader9_Release(sin_shader);
10247 IDirect3DVertexShader9_Release(cos_shader);
10250 static void loop_index_test(IDirect3DDevice9 *device) {
10251 const DWORD shader_code[] = {
10252 0xfffe0200, /* vs_2_0 */
10253 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10254 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10255 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
10256 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
10257 0x0000001d, /* endloop */
10258 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10259 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
10260 0x0000ffff /* END */
10262 IDirect3DVertexShader9 *shader;
10263 HRESULT hr;
10264 DWORD color;
10265 const float quad[] = {
10266 -1.0, -1.0, 0.1,
10267 1.0, -1.0, 0.1,
10268 -1.0, 1.0, 0.1,
10269 1.0, 1.0, 0.1
10271 const float zero[4] = {0, 0, 0, 0};
10272 const float one[4] = {1, 1, 1, 1};
10273 int i0[4] = {2, 10, -3, 0};
10274 float values[4];
10276 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10277 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10278 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10279 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10280 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10281 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10283 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10285 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10286 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10287 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10288 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10289 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10290 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10291 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10293 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10294 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10295 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10296 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10297 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10298 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10299 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10300 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10301 values[0] = 1.0;
10302 values[1] = 1.0;
10303 values[2] = 0.0;
10304 values[3] = 0.0;
10305 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10306 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10307 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10308 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10309 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10310 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10311 values[0] = -1.0;
10312 values[1] = 0.0;
10313 values[2] = 0.0;
10314 values[3] = 0.0;
10315 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10316 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10317 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10318 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10319 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10320 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10321 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10322 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10323 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10324 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10326 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10327 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10329 hr = IDirect3DDevice9_BeginScene(device);
10330 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10331 if(SUCCEEDED(hr))
10333 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10334 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10335 hr = IDirect3DDevice9_EndScene(device);
10336 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10338 color = getPixelColor(device, 320, 240);
10339 ok(color_match(color, 0x0000ff00, 1),
10340 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10341 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10344 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10345 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10346 IDirect3DVertexShader9_Release(shader);
10349 static void sgn_test(IDirect3DDevice9 *device) {
10350 const DWORD shader_code[] = {
10351 0xfffe0200, /* vs_2_0 */
10352 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
10353 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10354 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
10355 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10356 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
10357 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
10358 0x0000ffff /* end */
10360 IDirect3DVertexShader9 *shader;
10361 HRESULT hr;
10362 DWORD color;
10363 const float quad[] = {
10364 -1.0, -1.0, 0.1,
10365 1.0, -1.0, 0.1,
10366 -1.0, 1.0, 0.1,
10367 1.0, 1.0, 0.1
10370 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10371 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10372 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10373 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10374 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10375 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10376 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10377 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10379 hr = IDirect3DDevice9_BeginScene(device);
10380 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10381 if(SUCCEEDED(hr))
10383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10384 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10385 hr = IDirect3DDevice9_EndScene(device);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10388 color = getPixelColor(device, 320, 240);
10389 ok(color_match(color, 0x008000ff, 1),
10390 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10391 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10392 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10394 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10395 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10396 IDirect3DVertexShader9_Release(shader);
10399 static void viewport_test(IDirect3DDevice9 *device) {
10400 HRESULT hr;
10401 DWORD color;
10402 D3DVIEWPORT9 vp, old_vp;
10403 BOOL draw_failed = TRUE;
10404 const float quad[] =
10406 -0.5, -0.5, 0.1,
10407 0.5, -0.5, 0.1,
10408 -0.5, 0.5, 0.1,
10409 0.5, 0.5, 0.1
10412 memset(&old_vp, 0, sizeof(old_vp));
10413 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10414 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10417 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10419 /* Test a viewport with Width and Height bigger than the surface dimensions
10421 * TODO: Test Width < surface.width, but X + Width > surface.width
10422 * TODO: Test Width < surface.width, what happens with the height?
10424 * The expected behavior is that the viewport behaves like the "default"
10425 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
10426 * MinZ = 0.0, MaxZ = 1.0.
10428 * Starting with Windows 7 the behavior among driver versions is not
10429 * consistent. The SetViewport call is accepted on all drivers. Some
10430 * drivers(older nvidia ones) refuse to draw and return an error. Newer
10431 * nvidia drivers draw, but use the actual values in the viewport and only
10432 * display the upper left part on the surface.
10434 memset(&vp, 0, sizeof(vp));
10435 vp.X = 0;
10436 vp.Y = 0;
10437 vp.Width = 10000;
10438 vp.Height = 10000;
10439 vp.MinZ = 0.0;
10440 vp.MaxZ = 0.0;
10441 hr = IDirect3DDevice9_SetViewport(device, &vp);
10442 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10444 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10445 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10446 hr = IDirect3DDevice9_BeginScene(device);
10447 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10448 if(SUCCEEDED(hr))
10450 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10451 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10452 draw_failed = FAILED(hr);
10453 hr = IDirect3DDevice9_EndScene(device);
10454 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10457 if(!draw_failed)
10459 color = getPixelColor(device, 158, 118);
10460 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10461 color = getPixelColor(device, 162, 118);
10462 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10463 color = getPixelColor(device, 158, 122);
10464 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10465 color = getPixelColor(device, 162, 122);
10466 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
10468 color = getPixelColor(device, 478, 358);
10469 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
10470 color = getPixelColor(device, 482, 358);
10471 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10472 color = getPixelColor(device, 478, 362);
10473 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10474 color = getPixelColor(device, 482, 362);
10475 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10478 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10479 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10481 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10482 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10485 /* This test tests depth clamping / clipping behaviour:
10486 * - With software vertex processing, depth values are clamped to the
10487 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
10488 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
10489 * same as regular vertices here.
10490 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
10491 * Normal vertices are always clipped. Pretransformed vertices are
10492 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
10493 * - The viewport's MinZ/MaxZ is irrelevant for this.
10495 static void depth_clamp_test(IDirect3DDevice9 *device)
10497 const struct tvertex quad1[] =
10499 { 0.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10500 {640.0f, 0.0f, 5.0f, 1.0f, 0xff002b7f},
10501 { 0.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10502 {640.0f, 480.0f, 5.0f, 1.0f, 0xff002b7f},
10504 const struct tvertex quad2[] =
10506 { 0.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10507 {640.0f, 300.0f, 10.0f, 1.0f, 0xfff9e814},
10508 { 0.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10509 {640.0f, 360.0f, 10.0f, 1.0f, 0xfff9e814},
10511 const struct tvertex quad3[] =
10513 {112.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10514 {208.0f, 108.0f, 5.0f, 1.0f, 0xffffffff},
10515 {112.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10516 {208.0f, 204.0f, 5.0f, 1.0f, 0xffffffff},
10518 const struct tvertex quad4[] =
10520 { 42.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10521 {112.0f, 41.0f, 10.0f, 1.0f, 0xffffffff},
10522 { 42.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10523 {112.0f, 108.0f, 10.0f, 1.0f, 0xffffffff},
10525 const struct vertex quad5[] =
10527 { -0.5f, 0.5f, 10.0f, 0xff14f914},
10528 { 0.5f, 0.5f, 10.0f, 0xff14f914},
10529 { -0.5f, -0.5f, 10.0f, 0xff14f914},
10530 { 0.5f, -0.5f, 10.0f, 0xff14f914},
10532 const struct vertex quad6[] =
10534 { -1.0f, 0.5f, 10.0f, 0xfff91414},
10535 { 1.0f, 0.5f, 10.0f, 0xfff91414},
10536 { -1.0f, 0.25f, 10.0f, 0xfff91414},
10537 { 1.0f, 0.25f, 10.0f, 0xfff91414},
10540 D3DVIEWPORT9 vp;
10541 D3DCOLOR color;
10542 D3DCAPS9 caps;
10543 HRESULT hr;
10545 vp.X = 0;
10546 vp.Y = 0;
10547 vp.Width = 640;
10548 vp.Height = 480;
10549 vp.MinZ = 0.0;
10550 vp.MaxZ = 7.5;
10552 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10553 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10555 hr = IDirect3DDevice9_SetViewport(device, &vp);
10556 if(FAILED(hr))
10558 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10559 * the tests because the 7.5 is just intended to show that it doesn't have
10560 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10561 * viewport and continue.
10563 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10564 vp.MaxZ = 1.0;
10565 hr = IDirect3DDevice9_SetViewport(device, &vp);
10567 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10569 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
10570 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10573 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10575 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10577 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10579 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10581 hr = IDirect3DDevice9_BeginScene(device);
10582 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10584 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10585 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10588 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10590 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10592 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10593 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10596 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10597 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10598 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10601 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10603 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10604 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10609 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10610 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10612 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10613 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10615 hr = IDirect3DDevice9_EndScene(device);
10616 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10618 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
10620 color = getPixelColor(device, 75, 75);
10621 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10622 color = getPixelColor(device, 150, 150);
10623 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10624 color = getPixelColor(device, 320, 240);
10625 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10626 color = getPixelColor(device, 320, 330);
10627 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10628 color = getPixelColor(device, 320, 330);
10629 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
10631 else
10633 color = getPixelColor(device, 75, 75);
10634 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10635 color = getPixelColor(device, 150, 150);
10636 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10637 color = getPixelColor(device, 320, 240);
10638 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10639 color = getPixelColor(device, 320, 330);
10640 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10641 color = getPixelColor(device, 320, 330);
10642 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10645 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10646 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10648 vp.MinZ = 0.0;
10649 vp.MaxZ = 1.0;
10650 hr = IDirect3DDevice9_SetViewport(device, &vp);
10651 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10654 static void depth_bounds_test(IDirect3DDevice9 *device)
10656 const struct tvertex quad1[] =
10658 { 0, 0, 0.0f, 1, 0xfff9e814},
10659 { 640, 0, 0.0f, 1, 0xfff9e814},
10660 { 0, 480, 1.0f, 1, 0xfff9e814},
10661 { 640, 480, 1.0f, 1, 0xfff9e814},
10663 const struct tvertex quad2[] =
10665 { 0, 0, 0.6f, 1, 0xff002b7f},
10666 { 640, 0, 0.6f, 1, 0xff002b7f},
10667 { 0, 480, 0.6f, 1, 0xff002b7f},
10668 { 640, 480, 0.6f, 1, 0xff002b7f},
10670 const struct tvertex quad3[] =
10672 { 0, 100, 0.6f, 1, 0xfff91414},
10673 { 640, 100, 0.6f, 1, 0xfff91414},
10674 { 0, 160, 0.6f, 1, 0xfff91414},
10675 { 640, 160, 0.6f, 1, 0xfff91414},
10678 union {
10679 DWORD d;
10680 float f;
10681 } tmpvalue;
10683 IDirect3D9 *d3d = NULL;
10684 IDirect3DSurface9 *offscreen_surface = NULL;
10685 D3DCOLOR color;
10686 HRESULT hr;
10688 IDirect3DDevice9_GetDirect3D(device, &d3d);
10689 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10690 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10691 skip("No NVDB (depth bounds test) support\n");
10692 IDirect3D9_Release(d3d);
10693 return;
10695 IDirect3D9_Release(d3d);
10697 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10698 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10699 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10700 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10702 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10703 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10706 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10708 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10710 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10712 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10715 hr = IDirect3DDevice9_BeginScene(device);
10716 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10718 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10719 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10722 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10725 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10727 tmpvalue.f = 0.625;
10728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10729 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10731 tmpvalue.f = 0.75;
10732 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10733 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10736 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10738 tmpvalue.f = 0.75;
10739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10740 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10742 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10743 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10746 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10748 hr = IDirect3DDevice9_EndScene(device);
10749 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10751 color = getPixelColor(device, 150, 130);
10752 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10753 color = getPixelColor(device, 150, 200);
10754 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10755 color = getPixelColor(device, 150, 300-5);
10756 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10757 color = getPixelColor(device, 150, 300+5);
10758 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10759 color = getPixelColor(device, 150, 330);
10760 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10761 color = getPixelColor(device, 150, 360-5);
10762 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10763 color = getPixelColor(device, 150, 360+5);
10764 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10766 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10767 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10770 static void depth_buffer_test(IDirect3DDevice9 *device)
10772 static const struct vertex quad1[] =
10774 { -1.0, 1.0, 0.33f, 0xff00ff00},
10775 { 1.0, 1.0, 0.33f, 0xff00ff00},
10776 { -1.0, -1.0, 0.33f, 0xff00ff00},
10777 { 1.0, -1.0, 0.33f, 0xff00ff00},
10779 static const struct vertex quad2[] =
10781 { -1.0, 1.0, 0.50f, 0xffff00ff},
10782 { 1.0, 1.0, 0.50f, 0xffff00ff},
10783 { -1.0, -1.0, 0.50f, 0xffff00ff},
10784 { 1.0, -1.0, 0.50f, 0xffff00ff},
10786 static const struct vertex quad3[] =
10788 { -1.0, 1.0, 0.66f, 0xffff0000},
10789 { 1.0, 1.0, 0.66f, 0xffff0000},
10790 { -1.0, -1.0, 0.66f, 0xffff0000},
10791 { 1.0, -1.0, 0.66f, 0xffff0000},
10793 static const DWORD expected_colors[4][4] =
10795 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10796 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10797 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10798 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10801 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10802 unsigned int i, j;
10803 D3DVIEWPORT9 vp;
10804 D3DCOLOR color;
10805 HRESULT hr;
10807 vp.X = 0;
10808 vp.Y = 0;
10809 vp.Width = 640;
10810 vp.Height = 480;
10811 vp.MinZ = 0.0;
10812 vp.MaxZ = 1.0;
10814 hr = IDirect3DDevice9_SetViewport(device, &vp);
10815 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10818 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10820 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10822 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10824 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10825 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10826 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10828 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10829 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10830 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10831 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10832 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10833 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10834 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10835 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10836 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10837 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10838 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10840 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10841 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10842 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10843 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10845 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10846 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10847 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10848 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10850 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10851 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10853 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10855 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10856 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10857 hr = IDirect3DDevice9_BeginScene(device);
10858 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10860 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10861 hr = IDirect3DDevice9_EndScene(device);
10862 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10864 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10865 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10866 IDirect3DSurface9_Release(backbuffer);
10867 IDirect3DSurface9_Release(rt3);
10868 IDirect3DSurface9_Release(rt2);
10869 IDirect3DSurface9_Release(rt1);
10871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10872 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10874 hr = IDirect3DDevice9_BeginScene(device);
10875 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10877 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10880 hr = IDirect3DDevice9_EndScene(device);
10881 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10883 for (i = 0; i < 4; ++i)
10885 for (j = 0; j < 4; ++j)
10887 unsigned int x = 80 * ((2 * j) + 1);
10888 unsigned int y = 60 * ((2 * i) + 1);
10889 color = getPixelColor(device, x, y);
10890 ok(color_match(color, expected_colors[i][j], 0),
10891 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10895 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10896 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10899 /* Test that partial depth copies work the way they're supposed to. The clear
10900 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
10901 * the following draw should only copy back the part that was modified. */
10902 static void depth_buffer2_test(IDirect3DDevice9 *device)
10904 static const struct vertex quad[] =
10906 { -1.0, 1.0, 0.66f, 0xffff0000},
10907 { 1.0, 1.0, 0.66f, 0xffff0000},
10908 { -1.0, -1.0, 0.66f, 0xffff0000},
10909 { 1.0, -1.0, 0.66f, 0xffff0000},
10912 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
10913 unsigned int i, j;
10914 D3DVIEWPORT9 vp;
10915 D3DCOLOR color;
10916 HRESULT hr;
10918 vp.X = 0;
10919 vp.Y = 0;
10920 vp.Width = 640;
10921 vp.Height = 480;
10922 vp.MinZ = 0.0;
10923 vp.MaxZ = 1.0;
10925 hr = IDirect3DDevice9_SetViewport(device, &vp);
10926 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10929 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10931 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10933 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10935 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10936 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10937 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10939 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10940 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10941 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10942 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10943 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10944 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10945 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10946 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10948 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10949 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10951 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10953 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10954 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10955 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
10956 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10958 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10959 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10960 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10961 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10963 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10964 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10965 IDirect3DSurface9_Release(backbuffer);
10966 IDirect3DSurface9_Release(rt2);
10967 IDirect3DSurface9_Release(rt1);
10969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10970 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10972 hr = IDirect3DDevice9_BeginScene(device);
10973 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10975 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10976 hr = IDirect3DDevice9_EndScene(device);
10977 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10979 for (i = 0; i < 4; ++i)
10981 for (j = 0; j < 4; ++j)
10983 unsigned int x = 80 * ((2 * j) + 1);
10984 unsigned int y = 60 * ((2 * i) + 1);
10985 color = getPixelColor(device, x, y);
10986 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
10987 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
10991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10992 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10995 static void depth_blit_test(IDirect3DDevice9 *device)
10997 static const struct vertex quad1[] =
10999 { -1.0, 1.0, 0.50f, 0xff00ff00},
11000 { 1.0, 1.0, 0.50f, 0xff00ff00},
11001 { -1.0, -1.0, 0.50f, 0xff00ff00},
11002 { 1.0, -1.0, 0.50f, 0xff00ff00},
11004 static const struct vertex quad2[] =
11006 { -1.0, 1.0, 0.66f, 0xff0000ff},
11007 { 1.0, 1.0, 0.66f, 0xff0000ff},
11008 { -1.0, -1.0, 0.66f, 0xff0000ff},
11009 { 1.0, -1.0, 0.66f, 0xff0000ff},
11011 static const DWORD expected_colors[4][4] =
11013 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11014 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
11015 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
11016 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
11019 IDirect3DSurface9 *backbuffer, *ds1, *ds2;
11020 RECT src_rect, dst_rect;
11021 unsigned int i, j;
11022 D3DVIEWPORT9 vp;
11023 D3DCOLOR color;
11024 HRESULT hr;
11026 vp.X = 0;
11027 vp.Y = 0;
11028 vp.Width = 640;
11029 vp.Height = 480;
11030 vp.MinZ = 0.0;
11031 vp.MaxZ = 1.0;
11033 hr = IDirect3DDevice9_SetViewport(device, &vp);
11034 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
11036 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11037 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11038 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
11039 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11040 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
11041 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
11042 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
11043 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11046 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11048 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11050 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11051 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11052 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11054 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11055 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11056 SetRect(&dst_rect, 0, 0, 480, 360);
11057 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
11058 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11059 SetRect(&dst_rect, 0, 0, 320, 240);
11060 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
11061 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11063 /* Partial blit. */
11064 SetRect(&src_rect, 0, 0, 320, 240);
11065 SetRect(&dst_rect, 0, 0, 320, 240);
11066 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11067 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11068 /* Flipped. */
11069 SetRect(&src_rect, 0, 0, 640, 480);
11070 SetRect(&dst_rect, 0, 480, 640, 0);
11071 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11072 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11073 /* Full, explicit. */
11074 SetRect(&src_rect, 0, 0, 640, 480);
11075 SetRect(&dst_rect, 0, 0, 640, 480);
11076 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
11077 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11078 /* Filtered blit. */
11079 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
11080 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11081 /* Depth -> color blit.*/
11082 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
11083 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
11084 IDirect3DSurface9_Release(backbuffer);
11086 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
11087 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11088 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11089 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11090 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
11091 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
11092 IDirect3DSurface9_Release(ds2);
11093 IDirect3DSurface9_Release(ds1);
11095 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11096 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11097 hr = IDirect3DDevice9_BeginScene(device);
11098 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11100 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11101 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11102 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11103 hr = IDirect3DDevice9_EndScene(device);
11104 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11106 for (i = 0; i < 4; ++i)
11108 for (j = 0; j < 4; ++j)
11110 unsigned int x = 80 * ((2 * j) + 1);
11111 unsigned int y = 60 * ((2 * i) + 1);
11112 color = getPixelColor(device, x, y);
11113 ok(color_match(color, expected_colors[i][j], 0),
11114 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11118 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11119 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11122 static void intz_test(IDirect3DDevice9 *device)
11124 static const DWORD ps_code[] =
11126 0xffff0200, /* ps_2_0 */
11127 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11128 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11129 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11130 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11131 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11132 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11133 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11134 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11135 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
11136 0x0000ffff, /* end */
11138 struct
11140 float x, y, z;
11141 float s, t, p, q;
11143 quad[] =
11145 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
11146 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
11147 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
11148 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
11150 struct
11152 UINT x, y;
11153 D3DCOLOR color;
11155 expected_colors[] =
11157 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11158 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11159 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11160 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11161 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
11162 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
11163 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
11164 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
11167 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11168 IDirect3DTexture9 *texture;
11169 IDirect3DPixelShader9 *ps;
11170 IDirect3DSurface9 *ds;
11171 IDirect3D9 *d3d9;
11172 D3DCAPS9 caps;
11173 HRESULT hr;
11174 UINT i;
11176 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11177 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11178 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11180 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
11181 return;
11184 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11185 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11187 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11188 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
11189 if (FAILED(hr))
11191 skip("No INTZ support, skipping INTZ test.\n");
11192 return;
11195 IDirect3D9_Release(d3d9);
11197 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11198 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11199 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11200 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11202 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11203 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
11204 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11205 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11206 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11207 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11208 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11209 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11211 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11212 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11214 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11216 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11218 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11220 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11222 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11223 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11225 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11226 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11227 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11228 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11229 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11231 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11233 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11234 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11235 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11236 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11237 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11238 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11239 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11240 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11242 /* Setup the depth/stencil surface. */
11243 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11244 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11246 hr = IDirect3DDevice9_BeginScene(device);
11247 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11249 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11250 hr = IDirect3DDevice9_EndScene(device);
11251 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11253 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11254 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11255 IDirect3DSurface9_Release(ds);
11256 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11257 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11258 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11259 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11260 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11261 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11263 /* Read the depth values back. */
11264 hr = IDirect3DDevice9_BeginScene(device);
11265 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11267 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11268 hr = IDirect3DDevice9_EndScene(device);
11269 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11271 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
11273 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
11274 ok(color_match(color, expected_colors[i].color, 1),
11275 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
11276 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
11279 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11280 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11282 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11283 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11284 IDirect3DSurface9_Release(original_ds);
11285 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11286 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11287 IDirect3DTexture9_Release(texture);
11288 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11289 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11290 IDirect3DPixelShader9_Release(ps);
11292 IDirect3DSurface9_Release(original_rt);
11293 IDirect3DSurface9_Release(rt);
11296 static void shadow_test(IDirect3DDevice9 *device)
11298 static const DWORD ps_code[] =
11300 0xffff0200, /* ps_2_0 */
11301 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11302 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11303 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
11304 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11305 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11306 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
11307 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
11308 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
11309 0x02000001, 0x800f0800, 0x80e40001, /* mov 0C0, r1 */
11310 0x0000ffff, /* end */
11312 struct
11314 D3DFORMAT format;
11315 const char *name;
11317 formats[] =
11319 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
11320 {D3DFMT_D32, "D3DFMT_D32"},
11321 {D3DFMT_D15S1, "D3DFMT_D15S1"},
11322 {D3DFMT_D24S8, "D3DFMT_D24S8"},
11323 {D3DFMT_D24X8, "D3DFMT_D24X8"},
11324 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
11325 {D3DFMT_D16, "D3DFMT_D16"},
11326 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
11327 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
11329 struct
11331 float x, y, z;
11332 float s, t, p, q;
11334 quad[] =
11336 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11337 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11338 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11339 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11341 struct
11343 UINT x, y;
11344 D3DCOLOR color;
11346 expected_colors[] =
11348 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11349 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11350 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11351 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11352 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11353 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11354 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11355 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11358 IDirect3DSurface9 *original_ds, *original_rt, *rt;
11359 IDirect3DPixelShader9 *ps;
11360 IDirect3D9 *d3d9;
11361 D3DCAPS9 caps;
11362 HRESULT hr;
11363 UINT i;
11365 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11366 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11367 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11369 skip("No pixel shader 2.0 support, skipping shadow test.\n");
11370 return;
11373 hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11374 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11375 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11376 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11377 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11378 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11380 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11381 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11382 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11383 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11384 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11386 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11387 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11389 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11391 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11392 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11393 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11395 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11397 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11398 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11399 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11400 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11401 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11402 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11403 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11404 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11405 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11406 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11408 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11410 D3DFORMAT format = formats[i].format;
11411 IDirect3DTexture9 *texture;
11412 IDirect3DSurface9 *ds;
11413 unsigned int j;
11415 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11416 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11417 if (FAILED(hr)) continue;
11419 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11420 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11421 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11423 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11424 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11426 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11427 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11429 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11430 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11432 IDirect3DDevice9_SetPixelShader(device, NULL);
11433 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11435 /* Setup the depth/stencil surface. */
11436 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11437 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11439 hr = IDirect3DDevice9_BeginScene(device);
11440 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11442 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11443 hr = IDirect3DDevice9_EndScene(device);
11444 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11446 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11447 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11448 IDirect3DSurface9_Release(ds);
11450 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11451 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11453 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11454 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11456 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11457 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11459 /* Do the actual shadow mapping. */
11460 hr = IDirect3DDevice9_BeginScene(device);
11461 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11463 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11464 hr = IDirect3DDevice9_EndScene(device);
11465 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11467 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11468 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11469 IDirect3DTexture9_Release(texture);
11471 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11473 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11474 ok(color_match(color, expected_colors[j].color, 0),
11475 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11476 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11477 formats[i].name, color);
11480 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11481 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11484 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11485 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11486 IDirect3DPixelShader9_Release(ps);
11488 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11489 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11490 IDirect3DSurface9_Release(original_ds);
11492 IDirect3DSurface9_Release(original_rt);
11493 IDirect3DSurface9_Release(rt);
11495 IDirect3D9_Release(d3d9);
11498 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
11500 const struct vertex quad1[] =
11502 {-1.0f, -1.0f, 0.0f, 0xfff9e814},
11503 { 1.0f, -1.0f, 0.0f, 0xfff9e814},
11504 {-1.0f, 1.0f, 0.0f, 0xfff9e814},
11505 { 1.0f, 1.0f, 0.0f, 0xfff9e814},
11507 const struct vertex quad2[] =
11509 {-1.0f, -1.0f, 0.0f, 0xff002b7f},
11510 { 1.0f, -1.0f, 0.0f, 0xff002b7f},
11511 {-1.0f, 1.0f, 0.0f, 0xff002b7f},
11512 { 1.0f, 1.0f, 0.0f, 0xff002b7f},
11514 D3DCOLOR color;
11515 HRESULT hr;
11517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
11518 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11520 hr = IDirect3DDevice9_BeginScene(device);
11521 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11523 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11524 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11527 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11529 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
11532 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11534 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11536 hr = IDirect3DDevice9_EndScene(device);
11537 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11539 color = getPixelColor(device, 1, 240);
11540 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11541 color = getPixelColor(device, 638, 240);
11542 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
11544 color = getPixelColor(device, 1, 241);
11545 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11546 color = getPixelColor(device, 638, 241);
11547 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
11550 static void clip_planes_test(IDirect3DDevice9 *device)
11552 const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
11554 const DWORD shader_code[] = {
11555 0xfffe0200, /* vs_2_0 */
11556 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11557 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11558 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11559 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11560 0x0000ffff /* end */
11562 IDirect3DVertexShader9 *shader;
11564 IDirect3DTexture9 *offscreen = NULL;
11565 IDirect3DSurface9 *offscreen_surface, *original_rt;
11566 HRESULT hr;
11568 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11569 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11572 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11574 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11576 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
11578 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11580 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11581 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11582 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11583 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
11585 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
11587 clip_planes(device, "Onscreen FFP");
11589 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
11590 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11591 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
11592 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11593 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11596 clip_planes(device, "Offscreen FFP");
11598 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11599 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11601 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11602 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
11603 IDirect3DDevice9_SetVertexShader(device, shader);
11604 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
11606 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11607 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11609 clip_planes(device, "Onscreen vertex shader");
11611 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
11612 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11614 clip_planes(device, "Offscreen vertex shader");
11616 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11617 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11619 IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
11620 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11621 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
11622 IDirect3DVertexShader9_Release(shader);
11623 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11624 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11625 IDirect3DSurface9_Release(original_rt);
11626 IDirect3DSurface9_Release(offscreen_surface);
11627 IDirect3DTexture9_Release(offscreen);
11630 static void fp_special_test(IDirect3DDevice9 *device)
11632 static const DWORD vs_header[] =
11634 0xfffe0200, /* vs_2_0 */
11635 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11636 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11637 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
11640 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
11641 static const DWORD vs_pow[] =
11642 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
11643 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
11644 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
11645 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
11646 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
11647 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
11649 static const DWORD vs_footer[] =
11651 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
11652 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
11653 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
11654 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
11655 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11656 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
11657 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
11658 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
11659 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
11660 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
11661 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
11662 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
11663 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
11664 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
11665 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11666 0x0000ffff, /* end */
11669 static const struct
11671 const char *name;
11672 const DWORD *ops;
11673 DWORD size;
11674 D3DCOLOR r600;
11675 D3DCOLOR nv40;
11676 D3DCOLOR nv50;
11678 vs_body[] =
11680 /* The basic ideas here are:
11681 * 2.0 * +/-INF == +/-INF
11682 * NAN != NAN
11684 * The vertex shader value is written to the red component, with 0.0
11685 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11686 * result in 0x00. The pixel shader value is written to the green
11687 * component, but here 0.0 also results in 0x00. The actual value is
11688 * written to the blue component.
11690 * There are considerable differences between graphics cards in how
11691 * these are handled, but pow and nrm never generate INF or NAN. */
11692 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00ff0000, 0x00ff7f00},
11693 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x0000ff00, 0x000000ff},
11694 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x0000ff00, 0x00ff0000},
11695 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11696 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x00000000, 0x00ff0000, 0x00ff7f00},
11697 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11698 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x00ff00ff, 0x00ff7f00},
11701 static const DWORD ps_code[] =
11703 0xffff0200, /* ps_2_0 */
11704 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
11705 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
11706 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
11707 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
11708 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
11709 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
11710 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
11711 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
11712 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
11713 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
11714 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
11715 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
11716 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
11717 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
11718 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
11719 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
11720 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
11721 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
11722 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
11723 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
11724 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
11725 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11726 0x0000ffff, /* end */
11729 struct
11731 float x, y, z;
11732 float s;
11734 quad[] =
11736 { -1.0f, 1.0f, 0.0f, 0.0f},
11737 { 1.0f, 1.0f, 1.0f, 0.0f},
11738 { -1.0f, -1.0f, 0.0f, 0.0f},
11739 { 1.0f, -1.0f, 1.0f, 0.0f},
11742 IDirect3DPixelShader9 *ps;
11743 UINT body_size = 0;
11744 DWORD *vs_code;
11745 D3DCAPS9 caps;
11746 HRESULT hr;
11747 UINT i;
11749 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11750 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11751 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11753 skip("No shader model 2.0 support, skipping floating point specials test.\n");
11754 return;
11757 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11758 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11760 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11761 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11762 IDirect3DDevice9_SetPixelShader(device, ps);
11763 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11766 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11768 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11769 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11771 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11773 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11776 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11777 memcpy(vs_code, vs_header, sizeof(vs_header));
11779 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11781 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11782 IDirect3DVertexShader9 *vs;
11783 D3DCOLOR color;
11785 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11786 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11787 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11789 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11790 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11791 IDirect3DDevice9_SetVertexShader(device, vs);
11792 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11794 hr = IDirect3DDevice9_BeginScene(device);
11795 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11796 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11797 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11798 hr = IDirect3DDevice9_EndScene(device);
11799 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11801 color = getPixelColor(device, 320, 240);
11802 ok(color_match(color, vs_body[i].r600, 1)
11803 || color_match(color, vs_body[i].nv40, 1)
11804 || color_match(color, vs_body[i].nv50, 1),
11805 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11806 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11809 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11811 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11812 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11813 IDirect3DVertexShader9_Release(vs);
11816 HeapFree(GetProcessHeap(), 0, vs_code);
11818 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11819 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11820 IDirect3DPixelShader9_Release(ps);
11823 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11825 IDirect3D9 *d3d;
11826 IDirect3DSurface9 *rt, *backbuffer;
11827 IDirect3DTexture9 *texture;
11828 HRESULT hr;
11829 int i;
11830 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11831 static const struct
11833 D3DFORMAT fmt;
11834 const char *name;
11836 formats[] =
11838 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11839 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11840 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11841 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11842 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11844 static const struct
11846 float x, y, z;
11847 float u, v;
11849 quad[] =
11851 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
11852 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
11853 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
11854 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
11857 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11858 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11859 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11860 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11861 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11862 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11863 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11864 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11866 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11868 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11870 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11871 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11873 skip("Format %s not supported as render target, skipping test.\n",
11874 formats[i].name);
11875 continue;
11878 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11879 D3DPOOL_DEFAULT, &texture, NULL);
11880 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11882 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11884 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11885 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11886 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11887 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11889 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11891 hr = IDirect3DDevice9_BeginScene(device);
11892 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11893 if(SUCCEEDED(hr))
11895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11896 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11898 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11899 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11900 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11903 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11904 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11905 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11906 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11907 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11908 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11909 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11911 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11912 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11913 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11915 hr = IDirect3DDevice9_EndScene(device);
11916 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11919 IDirect3DSurface9_Release(rt);
11920 IDirect3DTexture9_Release(texture);
11922 color = getPixelColor(device, 360, 240);
11923 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11924 D3DUSAGE_QUERY_SRGBWRITE,
11925 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11927 /* Big slop for R5G6B5 */
11928 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11929 formats[i].name, color_srgb, color);
11931 else
11933 /* Big slop for R5G6B5 */
11934 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11935 formats[i].name, color_rgb, color);
11938 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11939 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11942 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11943 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11945 IDirect3D9_Release(d3d);
11946 IDirect3DSurface9_Release(backbuffer);
11949 static void ds_size_test(IDirect3DDevice9 *device)
11951 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
11952 HRESULT hr;
11953 DWORD color;
11954 DWORD num_passes;
11955 struct
11957 float x, y, z;
11959 quad[] =
11961 {-1.0, -1.0, 0.0 },
11962 {-1.0, 1.0, 0.0 },
11963 { 1.0, -1.0, 0.0 },
11964 { 1.0, 1.0, 0.0 }
11967 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11968 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
11969 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
11970 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
11971 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11972 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11974 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11975 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11977 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11979 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
11980 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11981 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11982 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
11983 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
11984 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
11985 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
11986 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11987 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
11988 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11989 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
11990 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
11991 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
11993 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
11994 * but does not change the surface's contents. */
11995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
11996 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
11997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
11998 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
11999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
12000 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
12002 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
12003 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTargetData failed, hr %#x.\n", hr);
12004 color = getPixelColorFromSurface(readback, 2, 2);
12005 ok(color == 0x000000FF, "DS size test: Pixel (2, 2) after clear is %#x, expected 0x000000FF\n", color);
12006 color = getPixelColorFromSurface(readback, 31, 31);
12007 ok(color == 0x000000FF, "DS size test: Pixel (31, 31) after clear is %#x, expected 0x000000FF\n", color);
12008 color = getPixelColorFromSurface(readback, 32, 32);
12009 ok(color == 0x000000FF, "DS size test: Pixel (32, 32) after clear is %#x, expected 0x000000FF\n", color);
12010 color = getPixelColorFromSurface(readback, 63, 63);
12011 ok(color == 0x000000FF, "DS size test: Pixel (63, 63) after clear is %#x, expected 0x000000FF\n", color);
12013 /* Turning on any depth-related state results in a ValidateDevice failure */
12014 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12015 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12016 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12017 ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12018 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12020 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12022 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
12023 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12024 ok(hr == D3DERR_CONFLICTINGRENDERSTATE, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
12025 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
12027 /* Try to draw with the device in an invalid state */
12028 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12029 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12030 hr = IDirect3DDevice9_BeginScene(device);
12031 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12032 if(SUCCEEDED(hr))
12034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12035 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12036 hr = IDirect3DDevice9_EndScene(device);
12037 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12040 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12042 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
12043 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
12044 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
12045 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
12047 IDirect3DSurface9_Release(readback);
12048 IDirect3DSurface9_Release(ds);
12049 IDirect3DSurface9_Release(rt);
12050 IDirect3DSurface9_Release(old_rt);
12051 IDirect3DSurface9_Release(old_ds);
12054 static void unbound_sampler_test(IDirect3DDevice9 *device)
12056 HRESULT hr;
12057 IDirect3DPixelShader9 *ps;
12058 IDirect3DSurface9 *rt, *old_rt;
12059 DWORD color;
12061 static const DWORD ps_code[] =
12063 0xffff0200, /* ps_2_0 */
12064 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
12065 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
12066 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
12067 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
12068 0x0000ffff, /* end */
12071 static const struct
12073 float x, y, z;
12074 float u, v;
12076 quad[] =
12078 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
12079 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
12080 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
12081 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
12084 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12085 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
12087 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
12088 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
12090 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
12091 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
12093 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
12094 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
12096 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12097 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12099 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
12100 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
12102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x56ffffff, 0, 0);
12103 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
12105 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12106 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12108 hr = IDirect3DDevice9_BeginScene(device);
12109 ok(SUCCEEDED(hr), "IDirect3DDevice9_BeginScene failed, hr %#x.\n", hr);
12110 if(SUCCEEDED(hr))
12112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12113 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#x.\n", hr);
12115 hr = IDirect3DDevice9_EndScene(device);
12116 ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene failed, hr %#x.\n", hr);
12119 color = getPixelColorFromSurface(rt, 32, 32);
12120 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
12122 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
12123 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
12125 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12126 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
12128 IDirect3DSurface9_Release(rt);
12129 IDirect3DSurface9_Release(old_rt);
12130 IDirect3DPixelShader9_Release(ps);
12133 static void update_surface_test(IDirect3DDevice9 *device)
12135 static const BYTE blocks[][8] =
12137 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
12138 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
12139 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
12140 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
12141 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
12142 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
12143 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
12145 static const struct
12147 UINT x, y;
12148 D3DCOLOR color;
12150 expected_colors[] =
12152 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
12153 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
12154 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
12155 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12156 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
12157 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
12158 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
12160 static const struct
12162 float x, y, z, w;
12163 float u, v;
12165 tri[] =
12167 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
12168 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
12169 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
12171 static const RECT rect_2x2 = {0, 0, 2, 2};
12172 static const struct
12174 UINT src_level;
12175 UINT dst_level;
12176 const RECT *r;
12177 HRESULT hr;
12179 block_size_tests[] =
12181 {1, 0, NULL, D3D_OK},
12182 {0, 1, NULL, D3DERR_INVALIDCALL},
12183 {5, 4, NULL, D3DERR_INVALIDCALL},
12184 {4, 5, NULL, D3DERR_INVALIDCALL},
12185 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
12186 {5, 5, &rect_2x2, D3D_OK},
12189 IDirect3DSurface9 *src_surface, *dst_surface;
12190 IDirect3DTexture9 *src_tex, *dst_tex;
12191 IDirect3D9 *d3d;
12192 UINT count, i;
12193 HRESULT hr;
12195 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
12196 ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
12198 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12199 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1);
12200 IDirect3D9_Release(d3d);
12201 if (FAILED(hr))
12203 skip("DXT1 not supported, skipping test.\n");
12204 return;
12207 IDirect3D9_Release(d3d);
12209 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
12210 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12211 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
12212 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
12214 count = IDirect3DTexture9_GetLevelCount(src_tex);
12215 ok(count == 7, "Got level count %u, expected 7.\n", count);
12217 for (i = 0; i < count; ++i)
12219 UINT row_count, block_count, x, y;
12220 D3DSURFACE_DESC desc;
12221 BYTE *row, *block;
12222 D3DLOCKED_RECT r;
12224 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
12225 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
12227 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
12228 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
12230 row_count = ((desc.Height + 3) & ~3) / 4;
12231 block_count = ((desc.Width + 3) & ~3) / 4;
12232 row = r.pBits;
12234 for (y = 0; y < row_count; ++y)
12236 block = row;
12237 for (x = 0; x < block_count; ++x)
12239 memcpy(block, blocks[i], sizeof(blocks[i]));
12240 block += sizeof(blocks[i]);
12242 row += r.Pitch;
12245 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
12246 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
12249 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
12251 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
12252 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12253 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
12254 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12256 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
12257 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
12258 hr, i, block_size_tests[i].hr);
12260 IDirect3DSurface9_Release(dst_surface);
12261 IDirect3DSurface9_Release(src_surface);
12264 for (i = 0; i < count; ++i)
12266 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
12267 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12268 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
12269 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
12271 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
12272 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
12274 IDirect3DSurface9_Release(dst_surface);
12275 IDirect3DSurface9_Release(src_surface);
12278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12279 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
12280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
12281 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
12282 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
12283 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
12284 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
12285 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12286 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12287 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12288 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12289 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12291 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
12292 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
12294 hr = IDirect3DDevice9_BeginScene(device);
12295 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
12296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
12297 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
12298 hr = IDirect3DDevice9_EndScene(device);
12299 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
12301 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
12303 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
12304 ok(color_match(color, expected_colors[i].color, 0),
12305 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
12306 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
12309 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12310 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
12312 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
12313 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
12314 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
12315 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
12316 IDirect3DTexture9_Release(dst_tex);
12317 IDirect3DTexture9_Release(src_tex);
12320 START_TEST(visual)
12322 IDirect3DDevice9 *device_ptr;
12323 D3DCAPS9 caps;
12324 HRESULT hr;
12325 DWORD color;
12327 d3d9_handle = LoadLibraryA("d3d9.dll");
12328 if (!d3d9_handle)
12330 skip("Could not load d3d9.dll\n");
12331 return;
12334 device_ptr = init_d3d9();
12335 if (!device_ptr)
12337 skip("Creating the device failed\n");
12338 return;
12341 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
12343 /* Check for the reliability of the returned data */
12344 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12345 if(FAILED(hr))
12347 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12348 goto cleanup;
12351 color = getPixelColor(device_ptr, 1, 1);
12352 if(color !=0x00ff0000)
12354 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12355 goto cleanup;
12357 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12359 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
12360 if(FAILED(hr))
12362 skip("Clear failed, can't assure correctness of the test results, skipping\n");
12363 goto cleanup;
12366 color = getPixelColor(device_ptr, 639, 479);
12367 if(color != 0x0000ddee)
12369 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
12370 goto cleanup;
12372 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
12374 /* Now execute the real tests */
12375 depth_clamp_test(device_ptr);
12376 stretchrect_test(device_ptr);
12377 lighting_test(device_ptr);
12378 clear_test(device_ptr);
12379 color_fill_test(device_ptr);
12380 fog_test(device_ptr);
12381 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
12383 test_cube_wrap(device_ptr);
12384 } else {
12385 skip("No cube texture support\n");
12387 z_range_test(device_ptr);
12388 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
12390 maxmip_test(device_ptr);
12392 else
12394 skip("No mipmap support\n");
12396 offscreen_test(device_ptr);
12397 ds_size_test(device_ptr);
12398 alpha_test(device_ptr);
12399 shademode_test(device_ptr);
12400 srgbtexture_test(device_ptr);
12401 release_buffer_test(device_ptr);
12402 float_texture_test(device_ptr);
12403 g16r16_texture_test(device_ptr);
12404 pixelshader_blending_test(device_ptr);
12405 texture_transform_flags_test(device_ptr);
12406 autogen_mipmap_test(device_ptr);
12407 fixed_function_decl_test(device_ptr);
12408 conditional_np2_repeat_test(device_ptr);
12409 fixed_function_bumpmap_test(device_ptr);
12410 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
12411 stencil_cull_test(device_ptr);
12412 } else {
12413 skip("No two sided stencil support\n");
12415 pointsize_test(device_ptr);
12416 tssargtemp_test(device_ptr);
12417 np2_stretch_rect_test(device_ptr);
12418 yuv_color_test(device_ptr);
12419 zwriteenable_test(device_ptr);
12420 alphatest_test(device_ptr);
12421 viewport_test(device_ptr);
12423 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12425 test_constant_clamp_vs(device_ptr);
12426 test_compare_instructions(device_ptr);
12428 else skip("No vs_1_1 support\n");
12430 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
12432 test_mova(device_ptr);
12433 loop_index_test(device_ptr);
12434 sincos_test(device_ptr);
12435 sgn_test(device_ptr);
12436 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12437 test_vshader_input(device_ptr);
12438 test_vshader_float16(device_ptr);
12439 stream_test(device_ptr);
12440 } else {
12441 skip("No vs_3_0 support\n");
12444 else skip("No vs_2_0 support\n");
12446 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12448 fog_with_shader_test(device_ptr);
12450 else skip("No vs_1_1 and ps_1_1 support\n");
12452 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
12454 texbem_test(device_ptr);
12455 texdepth_test(device_ptr);
12456 texkill_test(device_ptr);
12457 x8l8v8u8_test(device_ptr);
12458 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
12459 constant_clamp_ps_test(device_ptr);
12460 cnd_test(device_ptr);
12461 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
12462 dp2add_ps_test(device_ptr);
12463 unbound_sampler_test(device_ptr);
12464 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
12465 nested_loop_test(device_ptr);
12466 pretransformed_varying_test(device_ptr);
12467 vFace_register_test(device_ptr);
12468 vpos_register_test(device_ptr);
12469 multiple_rendertargets_test(device_ptr);
12470 } else {
12471 skip("No ps_3_0 or vs_3_0 support\n");
12473 } else {
12474 skip("No ps_2_0 support\n");
12478 else skip("No ps_1_1 support\n");
12480 texop_test(device_ptr);
12481 texop_range_test(device_ptr);
12482 alphareplicate_test(device_ptr);
12483 dp3_alpha_test(device_ptr);
12484 depth_buffer_test(device_ptr);
12485 depth_buffer2_test(device_ptr);
12486 depth_blit_test(device_ptr);
12487 intz_test(device_ptr);
12488 shadow_test(device_ptr);
12489 fp_special_test(device_ptr);
12490 depth_bounds_test(device_ptr);
12491 srgbwrite_format_test(device_ptr);
12492 clip_planes_test(device_ptr);
12493 update_surface_test(device_ptr);
12495 cleanup:
12496 if(device_ptr) {
12497 D3DPRESENT_PARAMETERS present_parameters;
12498 IDirect3DSwapChain9 *swapchain;
12499 ULONG ref;
12501 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
12502 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
12503 IDirect3DSwapChain9_Release(swapchain);
12504 ref = IDirect3DDevice9_Release(device_ptr);
12505 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
12506 DestroyWindow(present_parameters.hDeviceWindow);